2010-01-06 2 views
3

У меня простая ситуация (.NET2): texbox1 в UserControl1 (или Form1).Помогите настроить фокус на родителя

Я хочу unfocus (отпуска) в texbox, когда я нажимаю на UserControl/форма (фокус на UserControl/форму, а): alt text http://lh3.ggpht.com/_1TPOP7DzY1E/S0R1ORVt-pI/AAAAAAAAC3Y/UkS2zEMWa9o/s800/Capture4.png

я следующий на UC/форма:

 Protected Overrides Sub OnMouseClick _ 
      (ByVal e As System.Windows.Forms.MouseEventArgs) 
     MyBase.OnMouseClick(e) 
     Me.Focus() 
     End Sub 

Почему это не работает на ребенка текстовое поле, но очень хорошо работает на не-ребенок один (фокус на TextBox2 затем нажмите на панели снимает фокус с TextBox2)?

Реальный проект Window

alt text http://lh5.ggpht.com/_1TPOP7DzY1E/S0SVniaeN1I/AAAAAAAAC3g/jafhFG-vA0g/s800/Capture5.png

ответ

3
  1. Добавить новый элемент управления панели в форму (где-то в сторону) и изменить его размер до 0,0
  2. НЕ устанавливайте Visible = ложна на этой панели.
  3. В вашей форме добавить стандартный обработчик события MouseClick следующим образом:

    private void Form1_MouseClick(object sender, MouseEventArgs e) 
    { 
        // Uncomment if in scrollable control 
        //Point scrollPos = new Point(this.AutoScrollPosition.X, -this.AutoScrollPosition.Y); 
        newPanel.Select(); 
        // Uncomment if in scrollable control 
        //this.AutoScrollPosition = scrollPos; 
    
    } 
    
  4. Теперь, когда вы щелкните в любом месте на главной форме, любой входной контроль потеряет фокус, и вы будете в состоянии справиться с обычными Ожидающим события и т. д.
+0

спасибо, Ash, это работает :) – serhio

+0

Рад помочь :) Похоже, что интересный контроль вы строите. – Ash

0

лучше просто поймать событие мыши на вашем UserControl и установить фокус на себя. Это автоматически выведет фокус из текстового поля.

+0

это ** точно ** что я делаю. – serhio

2

Вы боретесь со встроенным поведением как класса Form, так и класса UserControl. Они были написаны, чтобы никогда не принимать фокус, если они содержат какие-либо дочерние элементы управления, вместо этого они автоматически перемещают фокус на ребенка. Встроенное поведение для класса ContainerControl, базового класса для обоих. GroupBox - еще один.

Это имеет большой смысл, если вы думаете об этом: ни один из них не может показать, что у них есть фокус, и нет ничего полезного, которое могло бы произойти, когда пользователь начнет печатать.

Не исправляйте это, это просто глубоко путает пользователя.

+0

Благодарю вас, дворяне. В реальном проекте у меня на панели есть текс-боксы, которые являются «3d» при фокусировке (режим редактирования) и плоской, когда нет (режим предварительного просмотра). Моя область трансформируется в плоском режиме, когда пользователь закончит редактирование и щелкнет где-нибудь еще (обычно на панели). – serhio

+0

Нет, пользователь нажмет на что-то, что выглядит интерактивным. Элемент управления, а не панель. Нет ничего, что приглашает щелчок на панели, это просто выглядит как «фон». Вам нужно было бы нарисовать бычьи глаза, чтобы это стало очевидным. Тогда это все еще не имеет смысла для пользователя, нет никакой подсказки, что делать дальше. –

+0

@nobugs: взгляните на реальное окно проекта, которое должно использовать щелчок на панели. Это временная диаграмма драйвера шины (x = часы, y = станции). Пользователь дважды нажимает на желтую метку, чтобы изменить час и редактирует новый час. Как, чтобы проверить его, можно щелкнуть в другом месте. Как это работает с мышью, наиболее удобным местом для щелчка является фоновая панель. Более того, тогда метод 'Фокус()' на панели работает с другими (не дочерними) элементами управления, даже если на панели есть дочерний элемент управления ... – serhio

2

Похоже, вы пытаетесь частично дублировать поведение, которое вы видите на диаграмме в Excel. Вы можете щелкнуть по любому объекту в диаграмме, и он выбран (с фокусом), но если вы выйдете за пределы области диаграммы, но все еще в объекте диаграммы, ничего не выбрано.

Это было бы очень знакомое поведение людей, привыкших к диаграммам в Excel.

В принципе, вам нужен элемент управления, который обычно принимает фокус. В прошлом я боролся с этой проблемой. Лучшее решение, которое я придумал (и «лучше всего», я не имею в виду, что это действительно хорошо) заключается в создании пустого текстового поля и размещении его за вашим UserControl. Тогда ваш код для нажатия на usercontrol выглядит так:

Protected Overrides Sub OnMouseClick _ 
      (ByVal e As System.Windows.Forms.MouseEventArgs) 
     MyBase.OnMouseClick(e) 
     myFakeTextBox.Focus() 
End Sub 

Пользователь никогда не видит, чтобы это текстовое поле получало фокус. Все, что они видят, состоит в том, что теперь в форме ничего не выбрано, и они могут свободно заниматься своим делом.

Этот метод работает очень хорошо, но с точки зрения обслуживания это немного головная боль, поскольку вы должны помнить, что фальшивый текстовый ящик есть и для чего он хорош.

+0

вам также придется переместить текстовое поле с помощью прокрутки, потому что если вы прокрутите куда-нибудь и нажмете на панель, положение прокрутки не должно меняться ... – serhio

+0

Да, хорошая точка. Я никогда не применял это, когда требовалась прокрутка. – Stewbob

Смежные вопросы