Использую библиотеку Hardcodet.Wpf.TaskbarNotification для отображения в трее иконки приложения:
<tb:TaskbarIcon x:Key="NotifyIcon"
IconSource="/Resources/iconOn.ico"
ToolTipText="{Binding Source={StaticResource Lang}, XPath=tt6}"
DoubleClickCommand="{Binding DoubleMouseClick}"
ContextMenu="{StaticResource SysTrayMenu}"
PreviewTrayContextMenuOpen="NotifyIcon_OnPreviewTrayContextMenuOpen">
<!-- self-assign a data context (could also be done programmatically) -->
<tb:TaskbarIcon.DataContext>
<mpAutoUpdater:NotifyIconViewModel/>
</tb:TaskbarIcon.DataContext>
</tb:TaskbarIcon>
Контекстное меню лежит в ресурсах. Особо смотреть там не на что. Для контекстного меню установлено свойство StaysOpen="False". Для пункта меню установлено свойство StaysOpenOnClick="False". К пункту меню привязана команда:
public ICommand CheckUpdatesCommand
{
get
{
return new DelegateCommand
{
CommandAction = () =>
{
ModuleUpdate.CheckAndUpdateModule(true);
Updater.CheckAndUpdateAll(true);
}
};
}
}
Реализация DelegateCommand взята прям из примера для библиотеки:
public class DelegateCommand : ICommand
{
public Action CommandAction { get; set; }
public Func<bool> CanExecuteFunc { get; set; }
public void Execute(object parameter)
{
CommandAction();
}
public bool CanExecute(object parameter)
{
return CanExecuteFunc == null || CanExecuteFunc();
}
public event EventHandler CanExecuteChanged
{
add => CommandManager.RequerySuggested += value;
remove => CommandManager.RequerySuggested -= value;
}
}
Так вот - при нажатии на пункт в меню контекстное меню продолжает отображаться открытым, пока выполняется код в команде. Я уже пробовал выносить в другой поток вот так:
public ICommand CheckUpdatesCommand
{
get
{
return new DelegateCommand
{
CommandAction = () =>
{
Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>
{
ModuleUpdate.CheckAndUpdateModule(true);
Updater.CheckAndUpdateAll(true);
}));
}
};
}
}
Бесполезно.
Что самое интересное - меню остается висеть не как нормальное меню, а как визуальный артефакт на экране. Т.е. оно уже не активно и по нему не кликнуть.
Я пробовал и ставить значение IsOpen="False" перед выполнением команды - тоже не помогло.
Что еще можно попробовать?
UPD: Добавляю gif'ку с отображением проблемы: при клике на пункт "Проверить обновления" работают методы, которые могут занять некоторое время (пару секунд). Они работают в основном потоке. И пока работа их не закончится - меню не исчезает. Вот это и нужно устранить
В общем получилось только вот так:
public ICommand CheckUpdatesCommand
{
get
{
return new DelegateCommand
{
CommandAction = async () =>
{
await Task.Run(async () =>
{
await Task.Delay(500);
void RunUpdaters()
{
ModuleUpdate.CheckAndUpdateModule(true);
Updater.CheckAndUpdateAll(true);
}
await Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(RunUpdaters));
});
}
};
}
}
Только в таком случае меню у меня пропадает перед началом работы.
P.S. Методы ModuleUpdate.CheckAndUpdateModule(true); и Updater.CheckAndUpdateAll(true); должны работать в основном потоке, так как там происходит много обращений к главному UI
Виртуальный выделенный сервер (VDS) становится отличным выбором
В окне кнопка, у которой свойство IsEnabled должно быть true только если Text в TextBox соответствует паттерну RegexА в других случаях false
Есть ajax запросРезультатом которого если всё хорошо будет срабатывать
Всем привет!Сразу извиняюсь, если очень глупо задал вопрос