События NotifyIcon не срабатывают

Я новичок здесь, и у меня действительно загадочная проблема для начала. Я разработчик программного обеспечения в Великобритании и имею более чем 15-летний опыт работы, но занимаюсь разработкой в ​​.Net всего 18 месяцев. Мои события мыши NotifyIcon не срабатывают!

Я использую С# для написания приложения, которое запускается как NotifyIcon («значок основного приложения») и отображает ContextMenu при щелчке правой кнопкой мыши. Это отлично работает: ContextMenu, запуск форм и запуск событий щелчка мыши.

Немного предыстории: предполагается, что приложение распознает вставку «устройства» USB (оно делает), опрашивает его и создает еще один NotifyIcon («значок устройства»), чтобы пользователь мог взаимодействовать с этим устройством. «Значок главного приложения», упомянутый в предыдущем абзаце, позволяет пользователю взаимодействовать с базой данных и настраивать программное обеспечение.

Чтобы инкапсулировать эти функции взаимодействия с устройством, я создал «класс устройства», который содержит устройство NotifyIcon, ContextMenu, формы, события щелчка мыши и т. д., которые позволяют взаимодействовать с устройством.

Проблема. Проблема начинается, когда я создаю свой "класс устройства" из события ManagementEventWatcher EventArrived. Если я создаю экземпляр «класса устройства» в своей программе Main, тогда события запускаются правильно, когда я нажимаю значок уведомления.

Итак, пожалуйста, кто-нибудь может мне помочь?

Привет, заранее

Мэтью


person user188999    schedule 13.10.2009    source источник


Ответы (3)


IIRC, использование event (а не WaitForNextEvent) работает асинхронно. Мне было бы интересно узнать, в какой теме поднимается событие. Интересно, нет ли сообщений, обслуживающих вашу иконку.

У вас есть форма где-нибудь? Или что-то еще с циклом сообщений? У меня возникло бы искушение позвонить в форму (используя Control.Invoke) и попросить форму показать значок — с тех пор у нее должен быть активный насос сообщений.


Извините за задержку; читая ваши комментарии, похоже, что у вас есть обходной путь. Единственная проблема — проблемы с несколькими нитями; в идеале вы должны попросить пользовательский интерфейс внести такое изменение в потоке пользовательского интерфейса; например, если у вас есть Form (владеющий значком) - добавьте в свой класс формы:

// not a property, as there is no need to add a complex x-thread "get"
public void SetIconVisible(bool isVisible) {
    if(this.InvokeRequired) {
        this.Invoke((MethodInvoker) delegate {
            myIcon.Visible = isVisible;
        });
    } else {
        myIcon.Visible = isVisible;
    }
}

Это переключает поток (при необходимости) на поток пользовательского интерфейса. Любое использование?

person Marc Gravell    schedule 13.10.2009
comment
Привет Марк Спасибо за быстрый ответ! Я слишком новичок в этом, чтобы ответить на ваши вопросы или понять предложение. Могу ли я каким-то образом сделать «насос сообщений», о котором вы говорите? У меня есть формы, но они отображаются только в ответ на упомянутое мной ContextMenus. О каком событии вы спрашиваете во втором предложении? Привет М - person user188999; 13.10.2009
comment
спасибо Марк. Мое исследование говорит мне, что мне нужно сделать несколько перекрестных потоков, что я только что понял. Что-то о делегатах и ​​вызове? чт - person user188999; 13.10.2009
comment
Марк, просто чтобы вы знали - я разработал, что могу создать экземпляры класса, которые имеют NotifyIcon в качестве членов в основном потоке, а затем сделать NotifyIcon (ы) видимыми, когда USB-устройство (я) подключено. Это потребовало небольшой настройки, потому что NotifyIcon создается, когда он впервые становится видимым, поэтому мне нужно было убедиться, что я установил для Visible значение true, а затем false для каждого. Затем поток ManagementEventWatcher может установить для свойства Visible значение true при подключении устройства. Обходной путь. - person user188999; 15.10.2009
comment
Мне действительно интересно узнать, как создать экземпляр класса в основном потоке (чтобы события срабатывали), но вычеркните это из потока ManagementEventWatcher, если у вас было время помочь? - person user188999; 15.10.2009

Итак, ответ:

События будут работать только в том случае, если вы сделаете видимым NotifyIcon в основном потоке. Таким образом, код, данный Марком Гравеллом, является решением.

person Jonas    schedule 21.01.2010

Марк, просто чтобы вы знали -

Я решил, что могу создать экземпляры класса, которые имеют NotifyIcon в качестве членов в основном потоке, а затем сделать видимыми NotifyIcon (ы), когда USB-устройства подключены.

Однако это потребовало небольшой настройки, потому что NotifyIcon создается, когда он впервые становится видимым, поэтому мне пришлось убедиться, что (в основном потоке) я установил для Visible значение true, а затем значение false для каждого, что привело к необходимости ограничения количество экземпляров.

Затем поток ManagementEventWatcher может установить для свойства Visible значение true при подключении устройства.

Обходной путь.

(см. ответы на ваши комментарии)

person user188999    schedule 15.10.2009
comment
добавил некоторые мысли - я надеюсь, что это поможет. - person Marc Gravell; 15.10.2009