#c# #wpf #ribbon-control
#c# #wpf #управление лентой
Вопрос:
Я работаю над приложением WPF на основе плагина. Плагины загружаются параллельно с использованием нескольких потоков. Один из плагинов — это плагин пользовательского интерфейса, который использует WPF RibbonWindow. Я пытаюсь добавить RibbonTab из плагина A в плагин пользовательского интерфейса.
Поскольку вызывающий поток не владеет RibbonWindow, я использую Dispatcher.Вызывается в RibbonWindow. К сожалению, код внутри делегата никогда не вызывается. Приложение по-прежнему реагирует, но вкладка не добавляется.
Могу ли я в любом случае получить доступ к потоку пользовательского интерфейса из другого плагина? Могу ли я создать поток, который можно поддерживать на протяжении всего моего приложения, чтобы я мог использовать этот поток для работы с RibbonWindow?
System.Threading.ThreadStart start = delegate()
{
log.Debug(Thread.CurrentThread.ManagedThreadId);
if (!this.Dispatcher.CheckAccess())
{
this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (ThreadStart)delegate() {
log.Debug(Thread.CurrentThread.ManagedThreadId);
ribbonRoot.Items.Add(myRibbonTab);
});
}
else {
log.Debug("We have access add directly.");
}
};
new Thread(start).Start();
Пожалуйста, дайте мне знать, если вам нужна какая-либо дополнительная информация.
Спасибо.
Ответ №1:
Вам нужно Application.Current.Dispatcher
вызвать его в потоке пользовательского интерфейса.
кстати: Почему вы ссылаетесь на ThreadStart? (не важно, просто любопытно)
Ответ №2:
Если вы просто хотите добавить вкладку ленты, вам не нужно запускать поток для этого (вы уже отправляете ее в поток пользовательского интерфейса), если только вы не хотите сделать в потоке больше. Даже тогда, возможно, было бы лучше использовать ThreadPool
вместо создания нового потока. В любом случае, в подобных сценариях я обычно передаю Dispatcher
из главного окна плагину через интерфейс плагина вместо прямого доступа к Application.Current.Dispatcher
. Делает его более инкапсулированным, и у вас есть лучший контроль над ним в модульных тестах.
Комментарии:
1. Спасибо за ваш ответ. Теперь я получаю
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.InvalidOperationException: The calling thread cannot access this object because a different thread owns it.
исключение. Я попытался создать ribbonwindow с помощью dispatcher, и это сделало приложение невосприимчивым. Пожалуйста, сообщите.2. Мне пришлось создавать каждую ribbontab с помощью приложения. Текущий. Диспетчер и это решило мою проблему. Спасибо за помощь.