Установить фокус на .NET UserControl ...? - PullRequest
12 голосов
/ 02 марта 2010

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

Пользовательский элемент управления содержит элемент управления ComboBox, и я рисую несколько строк рядом с ним.

ComboBox может получать фокус, но я бы хотел установить фокус на самом UserControl. Мой обработчик OnPaint настроен так, чтобы рисовать элемент управления немного иначе, если он имеет фокус, но я вызываю CanFocus () из родительской формы, когда создаю свой собственный элемент управления, и он возвращает false.

Есть свойство или что-то для установки?

Ответы [ 6 ]

21 голосов
/ 02 марта 2010

UserControl будет бороться с вашими зубами и ногтями, чтобы не получить фокус. У него есть код, который автоматически передает фокус дочернему элементу управления (если он есть), если он получает фокус. Вам как минимум придется переопределить WndProc () и перехватить сообщение WM_SETFOCUS. Может потребоваться другая операция, например ControlStyles.Selectable и свойства TabStop и TabIndex.

Ваша следующая проблема заключается в том, что UserControl не будет значимо отвечать, скажем, на сообщения клавиатуры, когда он имеет фокус. Вам нужно будет обнаружить щелчки на фоне UC для обработки сообщений мыши, а также переопределить рисование, чтобы для пользователя было очевидно, что UC имеет фокус (используйте ControlPaint.DrawFocusRectangle). Если это начинает звучать непривлекательно, то это потому, что UC действительно предназначался для управления контейнером.

1 голос
/ 01 марта 2014

В некоторых случаях также желательно, чтобы фокус не перемещался на дочерние элементы UserControl.
В этом случае вам также нужно установить ControlStyles.ContainerControl в false.

Public Sub New()
    InitializeComponent()

    Me.SetStyle(ControlStyles.ContainerControl, False)
    Me.SetStyle(ControlStyles.Selectable, True)

End Sub
1 голос
/ 02 марта 2010

слишком долго для комментария, содержит ссылку и код ... но это комментарий ...

Многие люди жаловались на то, что UserControl не запускает событие 'GotFocus (). Например: UserControl и GotFocus () fyi: LostFocus () будет запускаться, как и ожидалось, по моему опыту. В прошлом, в проекте с несколькими формами, я экспериментировал с реализацией обработчиков событий Enter и Leave в UserControl в каждой форме и обнаружил, что Enter вызывается только при загрузке формы один раз.

Очевидно, что элементы управления в UserControl "сфокусированы" (в некотором смысле, я не могу это объяснить, но, возможно, это сделает один из гуру SO ForForum). Возможно, это связано с тем, что UserControl происходит от ContainerControl?

Я экспериментировал с написанием одного обработчика GotFocus ():

    private void Control_GotFocus(object sender, EventArgs e)
    {
        Console.WriteLine("Control GotFocus : " + ((sender as Control).Name));
    }

А затем, в событии Load UserControl, подключил все элементы управления UserControl к этому обработчику событий: я заметил, что элемент управления UserControl с самым низким TabIndex будет запускать событие GotFocus только при запуске приложения и при переключении между формами.

Единственное, что я заметил в этой ситуации, это то, что свойство IsTabStop в UserControl установлено в значение True: это было от Шона Вильдермута из MS в контексте вопроса, связанного с SilverLight, поэтому нет Идея, если это может применяться в вашем случае.

Другое предложение, которое заключалось в написании обработчика событий MouseDown или MouseClick для UserControl, и в этом вызове: this.SetFocus(); меня ни к чему не привело.

Надеюсь, вы получите ответ!

1 голос
/ 02 марта 2010

С http://msdn.microsoft.com/en-us/library/system.windows.forms.control.canfocus.aspx

Примечания

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

Убедитесь, что вы выполнили эти предварительные требования.

0 голосов
/ 30 июня 2016

Если UserControl получает фокус, он внутренне передает фокус своему дочернему элементу управления.

Так что вам нужно пропустить выполнение кода, который устанавливает фокус на дочерний контроль. Для этого вам нужно переопределить WndProc (), чтобы пропустить выполнение любого сообщения WM_SETFOCUS.

 public class FocusableUserControl : UserControl
 {
    protected override void WndProc(ref Message m)
    {
        switch (m.Msg)
        {
            case (int)Win32Constants.WM_SETFOCUS:
            //Returning from here will skip setting focus to child controls.
            //It will not skip setting focus to this control.

                Console.WriteLine("FocusableUserControl is focused: " + Focused);
                return;
        }

        base.WndProc(ref m);
    }
}

Где WM_SETFOCUS - "0x0007".

0 голосов
/ 13 мая 2014

Скажем, у вас есть изображение в вашем пользовательском элементе управления, и вы хотите выделить его, имитируя событие "GetFocus" (скажем, фокусировка на вашем пользовательском элементе управления делает этот снимок). Сосредоточение внимания на вашем пользовательском элементе управления будет осуществляться путем рисования пунктирной линии в PictureBox. Это делается с помощью пользовательских элементов управления OnEnter и OnLeave. Вот процедура выделения ...

Public Sub highlightImage()
    Dim l As Single() = {2, 2, 2, 2}
    Dim p As New Pen(Color.Gray, 1)
    p.DashPattern = l
    Dim g As Graphics = picColor.CreateGraphics()
    g.DrawRectangle(p, 0, 0, picColor.Width - 1, picColor.Height - 1)
End Sub

Эти два переопределения выполнят эту работу.

Protected Overrides Sub OnEnter(e As EventArgs)
    MyBase.OnEnter(e)
    Me.highlightImage()
End Sub
Protected Overrides Sub OnLeave(e As EventArgs)
    MyBase.OnLeave(e)
    MyBase.Refresh()
End Sub
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...