Ограничить порядок табуляции одним пользовательским элементом управления

У меня есть пользовательский элемент управления, который ведет себя как плавающий элемент управления, и я хотел бы ограничить порядок табуляции только моим пользовательским элементом управления, когда он виден. В основном мне нужно иметь элемент управления, который ведет себя как Form без полей. На самом деле это был Form, но мне нужно было сохранить Фокус в окне MainForm, поэтому мне пришлось изменить его на UserControl.

Итак, представьте Form A (MainForm), а мой UserControl B. B является дочерним элементом управления A. Предположим, что форма A имеет кнопку и текстовое поле, а элемент управления B также имеет кнопку и текстовое поле. В настоящее время происходит следующая последовательность

Что сейчас происходит (естественное поведение табуляции):

Когда виден только A (B не виден):

1. The user manually focuses A textbox
2. Press tab key
3. A button is focused

Когда виден A, а также виден B: (ключ естественного порядка табуляции следующий):

1. The user manually focuses B textbox
2. Press tab key
3. B button is focused
4. Press tab key
5. A textbox is focused
6. Press tab key
7. A button is focused

Что мне нужно (мне нужно изменить пользовательский элемент управления, чтобы сохранить фокус):

Что мне действительно нужно, так это то, что элемент управления B сохраняет порядок табуляции внутри него, поэтому мне нужно, когда элемент управления B виден:

1. The user manually focuses B texbox
2. Press tab key
3. B button is focused
4. Press tab key
5. B textbox is focused

person Daniel Peñalba    schedule 23.03.2012    source источник
comment
Вы не должны этого делать - это нарушает возможность навигации для пользователей, использующих только клавиатуру (например, для людей с ослабленным зрением).   -  person    schedule 23.03.2012
comment
Мне нужно это сделать. Мой пользовательский элемент управления ведет себя как плавающий элемент управления. Текущее поведение странное.   -  person Daniel Peñalba    schedule 23.03.2012
comment
Конечно, вы могли бы отобразить свой пользовательский элемент управления в модальном диалоговом окне? Это похоже на то, что вы пытаетесь воспроизвести.   -  person    schedule 23.03.2012


Ответы (4)


Вы можете переопределить KeyDown элементов управления. событие и вручную переместите фокус на элемент управления, который должен получить фокус.

Кроме того, я согласен с Уиллом Хьюзом, что это может нарушить навигацию...

person Pedery    schedule 23.03.2012

Я предполагаю, что у вас есть кнопка, которую вы нажимаете, которая переключает видимость вашего пользовательского элемента управления B. И если он виден и имеет фокус, то сохраняет фокус. Он теряет фокус только тогда, когда вы переключаете его на скрытый. Если это так, вы можете попробовать этот код в своей форме A, которая будет держать ваш фокус в пользовательском элементе управления, если вы не скроете пользовательский элемент управления:

// store when we last clicked the toggle B user control visibility
private Stopwatch _sinceLastMouseClick;

public Form1()
{
    InitializeComponent();
    // instantiate the stopwatch and start it ticking
    _sinceLastMouseClick = new Stopwatch();
    _sinceLastMouseClick.Start();
}

Кнопка, которая переключает видимость обработчика кликов вашего плавающего элемента управления B:

private void btnToggleBUserControlVisibility_Click(object sender, EventArgs e)
{
    // reset the stopwatch because we just clicked it
    _sinceLastMouseClick.Restart();
    myUserControl1.Visible = !myUserControl1.Visible;
}

В родительской форме A обработайте событие Leave плавающего пользовательского элемента управления:

private void myUserControl1_Leave(object sender, EventArgs e)
{
    // see if the mouse is over the toggle button
    Point ptMouse = System.Windows.Forms.Control.MousePosition;
    Point ptClient = this.PointToClient(ptMouse);
    // if the mouse is NOT hovering over the toggle button and has NOT just clicked it,
    // then keep the focus in the user control.
    // We use the stopwatch to make sure that not only are we hovering over the button
    // but that we also clicked it, too
    if (btnToggleBUserControlVisibility != this.GetChildAtPoint(ptClient) ||
        _sinceLastMouseClick.ElapsedMilliseconds > 100)
    {
        myUserControl1.Focus();
    }
}
person Brad Rem    schedule 23.03.2012

Наконец, я решил проблему, включив следующий код в родительский элемент управления:

    private int WM_KEYDOWN = 0x100;

    public override bool PreProcessMessage(ref Message msg)
    {
        Keys key = (Keys)msg.WParam.ToInt32();

        if (msg.Msg == WM_KEYDOWN && key == Keys.Tab)
        {
            if (itemSearchControl.Visible)
            {
                bool moveForward = !IsShiftKeyPressed();
                bool result = itemSearchControl.SelectNextControl(itemSearchControl.ActiveControl, true, true, true, true);
                return true;
            }
        }

        return base.PreProcessMessage(ref msg);
    }
person Daniel Peñalba    schedule 26.03.2012

Из другого вопроса добавьте это в свой UserControl xaml.

KeyboardNavigation.TabNavigation="Cycle"

Ограничить порядок табуляции одним пользовательским элементом управления (WPF)

person midspace    schedule 22.05.2014