Если вы не инициализировали ссылочный тип и хотите установить или прочитать одно из его свойств, он будет генерировать исключение 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 не может произойти. Хотя вам нужно поддерживать оповещение при работе со ссылочными типами!
Только ссылочные типы, как следует из названия, могут содержать ссылки или буквально буквально ничто (или «нуль»). Если типы значений всегда содержат значение.
Типы ссылок (эти должны быть проверены):
Типы значений (вы можете просто игнорировать эти):
UserControl будет сражаться с вами зубами и гвоздями, чтобы избежать фокуса. Он имеет код, который автоматически передает фокус на дочерний элемент управления (если он есть), если он получает фокус. Вы, как минимум, должны переопределить WndProc () и заблокировать сообщение WM_SETFOCUS. Могут потребоваться другие операции, такие как ControlStyles.Selectable и свойства TabStop и TabIndex.
Ваша следующая проблема заключается в том, что UserControl не будет реагировать значимо, скажем, на сообщения клавиатуры, если у него есть фокус. Вам нужно будет обнаружить клики на фоне UC для обработки сообщений мыши, а также переопределить картину, так что для пользователя очевидно, что UC имеет фокус (используйте ControlPaint.DrawFocusRectangle). Если это начинает казаться непривлекательным, это потому, что UC действительно предназначался для управления контейнером.
В некоторых случаях также нежелательно не перемещать фокус на дочерние элементы UserControl. В этом случае вам также необходимо установить ControlStyles.ContainerControl в значение false.
Public Sub New()
InitializeComponent()
Me.SetStyle(ControlStyles.ContainerControl, False)
Me.SetStyle(ControlStyles.Selectable, True)
End Sub
слишком длинный для комментария, включает ссылку и код ... но это комментарий ...
Многие люди жаловались, что 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();
никуда не привел меня.
Надеюсь, вы получите ответ!
Из http://msdn.microsoft.com/en-us/library/system.windows.forms.control.canfocus.aspx
Замечания
Чтобы элемент управления получал фокус ввода, элемент управления должен иметь назначенный ему дескриптор, а свойства Visible и Enabled должны быть установлены как true для элемента управления и всех его родительских элементов управления, а также для управление должно быть формой, или самый внешний родительский элемент управления должен быть формой.
Убедитесь, что вы выполнили эти предварительные запросы.
Если 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».
Скажите, у вас есть изображение на вашем пользовательском элементе управления, и вы хотите выделить его, имитируя событие «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