【问题标题】:Wpf toolkit MessageBox style exceptionWpf 工具包 MessageBox 样式异常
【发布时间】:2019-04-11 15:02:37
【问题描述】:

我使用Xceed.Wpf.Toolkit.MessageBox显示一个对话框,我需要动态设置样式。

当我可以访问 UI 调度程序时,我只需调用 Show() 方法,将样式作为参数传递,一切正常。

但是当我无法访问我编写的 UI 线程时

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()

【问题讨论】:

    标签: c# wpf wpftoolkit


    【解决方案1】:

    您不能在后台线程上创建myStyle,然后将其应用于调度程序线程上的控件。您需要在同一个调度程序线程上创建它:

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

    【讨论】:

    • 嗯,你每天都能学到新东西!这就是问题所在,谢谢。但我不明白为什么我可以在后台线程上为消息框创建字符串和图像,而不是样式。
    • @farfetched:因为StyleDispatcherObject 并且它们具有线程关联性。
    猜你喜欢
    • 2016-08-20
    • 1970-01-01
    • 1970-01-01
    • 2011-02-19
    • 2011-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多