Ограничить порядок вкладок одним пользовательским элементом управления
У меня есть пользовательский элемент управления, который ведет себя как плавающий элемент управления, и я хотел бы ограничить порядок вкладок только для моего пользовательского элемента управления, когда он виден. В основном, мне нужно иметь контроль, который ведет себя как без границ Form
, На самом деле это был Form
, но мне нужно было сохранить Фокус в окне MainForm, поэтому мне пришлось изменить его на UserControl
,
Итак, представьте Form
A (MainForm) и мой UserControl
B. B является дочерним элементом управления A. Предположим, что форма A имеет кнопку и TextBox, а элемент управления 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
4 ответа
Наконец, я решил проблему, включив следующий код в родительский элемент управления:
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);
}
Из другого вопроса, добавьте это в свой UserControl xaml.
KeyboardNavigation.TabNavigation="Cycle"
Ограничить порядок вкладок одним пользовательским элементом управления (WPF)
Вы можете переопределить событие KeyDown элементов управления и вручную переместить фокус на элемент управления, который должен получить фокус.
Кроме того, я согласен с Уиллом Хьюзом, что это может нарушить навигацию...
Я предполагаю, что у вас есть какая-то кнопка, которую вы нажимаете, чтобы переключать видимость вашего пользовательского элемента управления 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();
}
}