Клавиша Tab и Navigation не запускает события KeyDown [дубликат]

Если вы не инициализировали ссылочный тип и хотите установить или прочитать одно из его свойств, он будет генерировать исключение NullReferenceException.

Пример:

Person p = null;
p.Name = "Harry"; // NullReferenceException occurs here.

Вы можно просто избежать этого, проверив, является ли переменная не нулевой:

Person p = null;
if (p!=null)
{
    p.Name = "Harry"; // Not going to run to this point
}

Чтобы полностью понять, почему выбрано исключение NullReferenceException, важно знать разницу между типами значений и ссылочные типы .

Итак, если вы имеете дело со типами значений, NullReferenceExceptions не может произойти. Хотя вам нужно поддерживать оповещение при работе со ссылочными типами!

Только ссылочные типы, как следует из названия, могут содержать ссылки или буквально буквально ничто (или «нуль»). Если типы значений всегда содержат значение.

Типы ссылок (эти должны быть проверены):

  • динамический
  • объект
  • string

Типы значений (вы можете просто игнорировать эти):

  • Числовые типы
  • Интегральные типы
  • Типы с плавающей запятой
  • decimal
  • bool
  • Пользовательские структуры

11
задан Sambo 2 March 2010 в 11:29
поделиться

6 ответов

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

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

21
ответ дан Scott Baker 27 August 2018 в 06:11
поделиться
  • 1
    Казалось, что эта работа. Я продолжу играть с ним, чтобы разобраться в тонкостях, которые вы упомянули. Благодаря! – Sambo 2 March 2010 в 13:48
  • 2
    +1 Рад получить еще один отличный ответ от NoBugz. Любопытно: в этом случае, по-вашему, OP может сделать лучше, используя форму вместо UserControl? – BillW 2 March 2010 в 15:20
  • 3
    @Bill: класс Form также является средством управления контейнером, хотя он не будет сопротивляться точно так же. Мой совет должен был бы избегать нестандартных пользовательских интерфейсов. Это смущает пользователя. – Hans Passant 2 March 2010 в 16:49
  • 4
    Если UserControl предназначался для управления контейнером, есть ли что-то, что мы можем извлечь из этого, который должен был стать настраиваемым элементом управления? Должны ли мы просто выводить из Control или ScrollableControl? – Trevor Elliott 22 June 2012 в 19:11
  • 5
    Я знаю, это было много лет назад ... но кто-то еще может ловушки на этот вопрос (как я). Здесь ссылка должна ответить на вопрос и очень проста – infero 6 August 2012 в 23:08

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

Public Sub New()
    InitializeComponent()

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

End Sub
1
ответ дан A.J.Bauer 27 August 2018 в 06:11
поделиться

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

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

Очевидно, что элементы управления UserControl «сосредоточены» (в некотором смысле я не могу объяснить, но, возможно, один из гуру SOF WinForms). Возможно, это связано с тем, что UserControl спускается из ContainerControl?

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

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

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

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

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

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

1
ответ дан BillW 27 August 2018 в 06:11
поделиться

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

Замечания

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

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

1
ответ дан David Waters 27 August 2018 в 06:11
поделиться
  • 1
    Спасибо за ваш ответ ... Я подтвердил, что мой контроль имеет значение для Handle. Элемент управления видимый и включен также, и панель, в которой я отображаю ее внутри, видима и включена, также ... и все это появляется в форме ...! Это похоже на предварительные требования ... Я перевернул OnGotFocus () и установил точку останова, но он никогда не попадал. Кроме того, я настроил обработчик в моем объекте формы для события GotFocus управления и, еще раз, код никогда не попадал. Любые другие идеи ...? – Sambo 2 March 2010 в 12:42
  • 2
    Эти предпосылки применяются к Control, но UserControl саботирует это как @HansPassant, упомянутое выше. – Scott Baker 23 September 2014 в 18:01

Если 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
ответ дан Kamalesh Wankhede 27 August 2018 в 06:11
поделиться

Скажите, у вас есть изображение на вашем пользовательском элементе управления, и вы хотите выделить его, имитируя событие «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
0
ответ дан Sam Saarian 27 August 2018 в 06:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: