У меня есть приложение Windows Form, которое использует класс Shared для размещения всех общих объектов приложения. Класс settings имеет коллекцию объектов, которые периодически что-то делают, а затем есть кое-что интересное, им нужно предупредить основную форму и обновить ее.
В настоящее время я делаю это через События на объектах, и когда каждый объект создается, я добавляю EventHandler, чтобы отобразить событие обратно в форму. Тем не менее, я сталкиваюсь с некоторыми проблемами, из-за которых эти запросы не всегда попадают в основную копию моей формы. Например, моя форма имеет значок в области уведомлений, но когда форма захватывает и событие и пытается отобразить пузырь, пузырь не появляется. Однако, если я изменю этот код, чтобы сделать значок видимым (хотя он уже есть), а затем отобразить пузырь, появится второй значок и правильно отобразит пузырь.
Кто-нибудь сталкивался с этим раньше? Есть ли способ, которым я могу заставить все свои события быть захваченными одним экземпляром формы, или есть совершенно другой способ справиться с этим? При необходимости я могу опубликовать примеры кода, но я думаю, что это общая проблема с многопоточностью.
ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ: В настоящее время я использую Me.InvokeRequired в обработчике событий в моей форме, и в этом случае он всегда возвращает FALSE. Кроме того, второй значок в трее, созданный, когда я делаю его видимым из этой формы, не имеет контекстного меню, в то время как "реальный" значок делает - кто-нибудь в этом подсказывает?
Я собираюсь вырвать мои волосы! Это не может быть так сложно!
РЕШЕНИЕ : Спасибо nobugz за подсказку, и это привело меня к коду, который я сейчас использую (который прекрасно работает, хотя я не могу не думать, что есть лучший способ сделать это) , Я добавил частную логическую переменную в форму с именем «IsPrimary» и добавил следующий код в конструктор формы:
Public Sub New()
If My.Application.OpenForms(0).Equals(Me) Then
Me.IsFirstForm = True
End If
End Sub
Как только эта переменная установлена и конструктор завершает работу, она направляется прямо к обработчику событий, и я имею дело с этим следующим образом (CAVEAT: поскольку искомая форма является основной формой приложения, My.Application .OpenForms (0) получает то, что мне нужно. Если бы я искал первый экземпляр не запускаемой формы, мне пришлось бы перебирать, пока я ее не нашел):
Public Sub EventHandler()
If Not IsFirstForm Then
Dim f As Form1 = My.Application.OpenForms(0)
f.EventHandler()
Me.Close()
ElseIf InvokeRequired Then
Me.Invoke(New HandlerDelegate(AddressOf EventHandler))
Else
' Do your event handling code '
End If
End Sub
Во-первых, он проверяет, работает ли он в правильной форме - если нет, то вызовите правильную форму. Затем он проверяет правильность потока и вызывает поток пользовательского интерфейса, если это не так. Затем запускается код события. Мне не нравится, что это потенциально три звонка, но я не могу придумать другой способ сделать это. Кажется, это работает хорошо, хотя это немного громоздко. Если у кого-то есть лучший способ сделать это, я хотел бы услышать это!
Опять же, спасибо за помощь - это сводило меня с ума!