Wpf toolkit MessageBox исключение стиля - PullRequest
0 голосов
/ 11 апреля 2019

Я использую Xceed.Wpf.Toolkit.MessageBox для отображения диалога, и мне нужно установить стиль динамически.

Когда у меня есть доступ к диспетчеру пользовательского интерфейса, я просто вызываю метод Show(), передавая стиль в качестве аргумента, и все идет правильно.

Но когда у меня нет доступа к потоку пользовательского интерфейса, я пишу

Application.Current.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() =>
{
    MessageBox.Show("Message Text", ..., myStyle);
}));

И, делая это, я получаю исключение:

Вызывающий поток не может получить доступ к этому объекту, поскольку он принадлежит другому потоку.

Конечно, при удалении стиля из аргументов не возникает исключение.
myStyle создается непосредственно в методе, не передается из другого потока или чего-либо еще.

Кто-нибудь знает , почему это происходит и как решить проблему ?

Трассировка стека:

at System.Windows.Threading.Dispatcher.VerifyAccess()
at System.Windows.Style.CheckTargetType(Object element)
at System.Windows.StyleHelper.UpdateStyleCache(FrameworkElement fe, FrameworkContentElement fce, Style oldStyle, Style newStyle, Style& styleCache)
at System.Windows.FrameworkElement.OnStyleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
at System.Windows.DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
at System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
at System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args)
at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType)
at System.Windows.DependencyObject.SetValueCommon(DependencyProperty dp, Object value, PropertyMetadata metadata, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType, Boolean isInternal)
at System.Windows.DependencyObject.SetValue(DependencyProperty dp, Object value)
at Xceed.Wpf.Toolkit.MessageBox.ShowCore(Window owner, IntPtr ownerHandle, String messageText, String caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult, Style messageBoxStyle)
at Xceed.Wpf.Toolkit.MessageBox.Show(Window owner, String messageText, String caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult, Style messageBoxStyle)
at MyNamespace.MyClass.<>c__DisplayClass1_0.<MyMethod>b__4() in C:\MyFile.cs:line 94
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
at System.Windows.Threading.DispatcherOperation.InvokeImpl()
at MS.Internal.CulturePreservingExecutionContext.CallbackWrapper(Object obj)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at MS.Internal.CulturePreservingExecutionContext.Run(CulturePreservingExecutionContext executionContext, ContextCallback callback, Object state)
at System.Windows.Threading.DispatcherOperation.Invoke()
at System.Windows.Threading.Dispatcher.ProcessQueue()
at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
at System.Windows.Window.ShowHelper(Object booleanBox)
at System.Windows.Window.ShowDialog()

1 Ответ

1 голос
/ 11 апреля 2019

Вы не можете создать myStyle в фоновом потоке и затем применить его к элементу управления в потоке диспетчера. Вам нужно создать его в том же потоке диспетчера:

Application.Current.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() =>
{
    //create myStyle here...
    var myStyle = ...;
    MessageBox.Show("Message Text", ..., myStyle);
}));
...