将选项卡顺序限制为单个用户控件
本文关键字:单个 用户 控件 选项 顺序 | 更新日期: 2023-09-27 18:28:51
我有一个充当浮动控件的用户控件,并且我希望将选项卡顺序仅限于可见的用户控件。基本上,我需要的是拥有一个行为像无边界Form
的控件。实际上它是一个Form
,但我需要在MainForm窗口中保留Focus,所以我不得不将其更改为UserControl
。
假设一个Form
A(MainForm),我的UserControl
B是a的子控件。假设Form a有一个按钮和一个TextBox,控件B也有一个按键和一个TextBox。目前发生的安全性是以下
当前发生的情况(自然制表顺序行为):
当只有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
您可以覆盖Controls的KeyDown事件,并手动将焦点移动到应该接收焦点的控件上。
除此之外,我同意Will Hughes的观点,认为这可能会破坏导航。。。
我假设您按下了一些按钮,可以切换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();
}
}
最后我解决了这个问题,包括父控件中的以下代码:
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)