2012-03-23 4 views
1

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

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

Что в настоящее время происходит (поведение естественного порядка вкладки):

когда только видно (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 
+0

Вы не должны делать это - он нарушает навигационную способность для клавиатуры только для пользователей (например, смотровые обесцененные люди) –

+0

I ** потребность **, чтобы сделать это. Мое пользовательское управление ведет себя как плавающее управление. Нынешнее поведение странно. –

+0

Несомненно, вы можете отображать свой пользовательский контроль в модальном диалоговом окне? Это похоже на то, что вы пытаетесь воспроизвести. –

ответ

0

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

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); 
    } 
0

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

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

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; 
} 

в родителе форма, ручка 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(); 
    } 
} 
Смежные вопросы