1

フローティング コントロールとして動作するユーザー コントロールがあり、表示されているユーザー コントロールのみにタブ オーダーを制限したいと考えています。基本的に必要なのは、ボーダーレスのように動作するコントロールを持つことFormです。実際には でしたFormが、MainForm ウィンドウにフォーカスを保持する必要があったため、 に変更する必要がありましたUserControl

B は A の子コントロールです。フォーム A にはボタンと TextBox があり、コントロール B にもボタンと Textbox があるとしFormます。UserControl現在発生しているシークエンスは次のとおりです。

現在何が起こっているか(自然なタブ オーダーの動作):

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

4 に答える 4

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

コントロールの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 に答える