1

我有一个充当浮动控件的用户控件,并且我想将选项卡顺序限制在我的用户控件可见时。基本上我需要的是有一个行为像无边界的控件Form。实际上它是Form一个UserControl.

所以,想象一个FormA(MainForm),而我的UserControlB。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 也可见时:(自然的 Tab 键顺序如下):

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 控件保留其中的 tab 顺序,所以我需要的是当 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

4 回答 4

0

您可以覆盖控件的KeyDown事件并手动将焦点移到应该接收焦点的控件上。

除此之外,我同意威尔休斯的观点,它可能会破坏导航......

于 2012-03-23T14:13:37.403 回答
0

我假设您按下了一些按钮来切换 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();
    }
}
于 2012-03-23T14:54:19.943 回答
0

最后我解决了这个问题,包括父控件中的以下代码:

    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);
    }
于 2012-03-26T07:45:10.223 回答
0

从另一个问题,将此添加到您的 UserControl xaml。

KeyboardNavigation.TabNavigation="Cycle"

将选项卡顺序限制为单个用户控件 (WPF)

于 2014-05-22T06:35:52.187 回答