从MaterialDesignInXamlToolkit使用我自己的DialogHost时获取InvalidOperationException

时间:2016-07-31 21:37:02

标签: c# xaml exception event-handling material-design-in-xaml

我使用Material Design library for WPF并尝试在单击按钮时打开对话框。调用DialogHost.Show(...)之后程序会中断以下消息

  

遍历树时超出了逻辑树深度。这可能表明树中有一个循环。

我已经尝试了解堆栈跟踪以及为什么会发生这种情况,但由于对库和MVVM架构的经验有限,似乎无法成功完成。

这是stacktrace

 StackTrace "
   at System.Windows.FrameworkElement.FindResourceInTree(FrameworkElement  feStart, FrameworkContentElement fceStart, DependencyProperty dp, Object resourceKey, Object unlinkedParent, Boolean allowDeferredResourceReference, Boolean mustReturnDeferredResourceReference, DependencyObject boundaryElement, InheritanceBehavior& inheritanceBehavior, Object& source)\r\n
   at System.Windows.FrameworkElement.FindResourceInternal(FrameworkElement fe, FrameworkContentElement fce, DependencyProperty dp, Object resourceKey, Object unlinkedParent, Boolean allowDeferredResourceReference, Boolean mustReturnDeferredResourceReference, DependencyObject boundaryElement, Boolean isImplicitStyleLookup, Object& source)\r\n
   at System.Windows.FrameworkElement.FindImplicitStyleResource(FrameworkElement fe, Object resourceKey, Object& source)\r\n
   at System.Windows.FrameworkElement.GetRawValue(DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry& entry)\r\n
   at System.Windows.FrameworkElement.EvaluateBaseValueCore(DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry& newEntry)\r\n
   at System.Windows.DependencyObject.EvaluateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry newEntry, OperationType operationType)\r\n
   at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType)\r\n
   at System.Windows.DependencyObject.InvalidateProperty(DependencyProperty dp, Boolean preserveCurrentValue)\r\n
   at System.Windows.FrameworkElement.UpdateStyleProperty()\r\n
   at System.Windows.TreeWalkHelper.InvalidateOnTreeChange(FrameworkElement fe, FrameworkContentElement fce, DependencyObject parent, Boolean isAddOperation)\r\n
   at System.Windows.FrameworkElement.ChangeLogicalParent(DependencyObject newParent)\r\n
   at System.Windows.FrameworkElement.AddLogicalChild(Object child)\r\n
   at System.Windows.Controls.ContentControl.OnContentChanged(Object oldContent, Object newContent)\r\n
   at System.Windows.Controls.ContentControl.OnContentChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)\r\n
   at System.Windows.DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs e)\r\n
   at System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e)\r\n
   at System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args)\r\n
   at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType)\r\n
   at System.Windows.DependencyObject.InvalidateProperty(DependencyProperty dp, Boolean preserveCurrentValue)\r\n
   at System.Windows.StyleHelper.InvalidateDependents(Style ownerStyle, FrameworkTemplate frameworkTemplate, DependencyObject container, DependencyProperty dp, FrugalStructList 1& dependents, Boolean invalidateOnlyContainer)\r\n
   at System.Windows.StyleHelper.OnTriggerSourcePropertyInvalidated(Style ownerStyle, FrameworkTemplate frameworkTemplate, DependencyObject container, DependencyProperty dp, DependencyPropertyChangedEventArgs changedArgs, Boolean invalidateOnlyContainer, FrugalStructList 1& triggerSourceRecordFromChildIndex, FrugalMap& propertyTriggersWithActions, Int32 sourceChildIndex)\r\n
   at System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e)\r\n
   at System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args)\r\n
   at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType)\r\n
   at System.Windows.DependencyObject.SetValueCommon(DependencyProperty dp, Object value, PropertyMetadata metadata, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType, Boolean isInternal)\r\n
   at System.Windows.DependencyObject.SetValue(DependencyProperty dp, Object value)\r\n
   at MaterialDesignThemes.Wpf.DialogHost.<ShowInternal>d__29.MoveNext() in C:\\projects\\materialdesigninxamltoolkit\\MaterialDesignThemes.Wpf\\DialogHost.cs:line 192\r\n--- End of stack trace from previous location where exception was thrown ---\r\n
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n
   at MaterialDesignThemes.Wpf.DialogHost.<Show>d__28.MoveNext() in C:\\projects\\materialdesigninxamltoolkit\\MaterialDesignThemes.Wpf\\DialogHost.cs:line 183\r\n--- End of stack trace from previous location where exception was thrown ---\r\n
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n
   at MaterialDesignThemes.Wpf.DialogHost.<Show>d__23.MoveNext() in C:\\projects\\materialdesigninxamltoolkit\\MaterialDesignThemes.Wpf\\DialogHost.cs:line 111\r\n--- End of stack trace from previous location where exception was thrown ---\r\n
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n
   at System.Runtime.CompilerServices.TaskAwaiter 1.GetResult()\r\n
   at SimpleUXApp_ForRizwan.MainWindow.<btn_Action_Click>d__5.MoveNext() in C:\\Users\\Paras\\Documents\\Visual Studio 2015\\Projects\\SimpleUXApp_ForRizwan\\SimpleUXApp_ForRizwan\\MainWindow.xaml.cs:line 99\r\n--- End of stack trace from previous location where exception was thrown ---\r\n
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.<>c.<ThrowAsync>b__6_0(Object state)\r\n
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)\r\n
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)\r\n
   at System.Windows.Threading.DispatcherOperation.InvokeImpl()\r\n
   at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state)\r\n
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)\r\n
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)\r\n
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)\r\n
   at MS.Internal.CulturePreservingExecutionContext.Run(CulturePreservingExecutionContext executionContext, ContextCallback callback, Object state)\r\n
   at System.Windows.Threading.DispatcherOperation.Invoke()\r\n
   at System.Windows.Threading.Dispatcher.ProcessQueue()\r\n
   at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)\r\n
   at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)\r\n
   at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)\r\n
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)\r\n
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)\r\n
   at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)\r\n
   at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)\r\n
   at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)\r\n
   at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)\r\n
   at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)\r\n
   at System.Windows.Application.RunDispatcher(Object ignore)\r\n
   at System.Windows.Application.RunInternal(Window window)\r\n
   at System.Windows.Application.Run(Window window)\r\n
   at System.Windows.Application.Run()\r\n
   at SimpleUXApp_ForRizwan.App.Main() in C:\\Users\\Paras\\Documents\\Visual Studio 2015\\Projects\\SimpleUXApp_ForRizwan\\SimpleUXApp_ForRizwan\\obj\\Debug\\App.g.cs:line 0\r\n
   at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)\r\n
   at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)\r\n
   at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()\r\n
   at System.Threading.ThreadHelper.ThreadStart_Context(Object state)\r\n
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)\r\n
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)\r\n
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)\r\n
   at System.Threading.ThreadHelper.ThreadStart()"  string

这是相关代码

来自 MainWindow.xaml.cs

摘录

    void CredsDialogClosingHandler(object sender, DialogClosingEventArgs e)
    {
        credentials = new UserCreds(txt_Password.SecurePassword);
        e.Handled = true;
    }

    private async void btn_Action_Click(object sender, RoutedEventArgs e)
    {
        if(credentials == null)
        {
            var getCreds = await DialogHost.Show(dialog_about, CredsDialogClosingHandler);
        }
    ...
    }
来自 MainWindow.xaml

摘录

    <materialDesign:DialogHost 
        Name="dialog_about"
        Grid.Row="2"
        HorizontalAlignment="Center" VerticalAlignment="Center" CloseOnClickAway="true">
        <materialDesign:DialogHost.DialogContent>
            <StackPanel Margin="16">
                <StackPanel Width="350" Height="200">
                    <Label 
                        HorizontalAlignment="Center" 
                        FontWeight="Medium"
                        FontSize="15"
                        Foreground="{DynamicResource PrimaryHueDarkBrush}"
                        Margin="0,15,0,10">
                        Password please
                    </Label>
                    <PasswordBox 
                        Name="txt_Password"
                        Margin="15,0,0,15" 
                        HorizontalAlignment="Center">
                    </PasswordBox>
                </StackPanel>

                <Button 
                    Name="btn_DialogClose"
                    Style="{StaticResource MaterialDesignRaisedButton}"
                    IsDefault="True"
                    Margin="0 8 8 0"
                    MaxWidth="100"
                    Command="{x:Static materialDesign:DialogHost.CloseDialogCommand}"
                    Content="Submit"/>
            </StackPanel>
        </materialDesign:DialogHost.DialogContent>
    </materialDesign:DialogHost>

Github Repo Cryption Utility

1 个答案:

答案 0 :(得分:2)

有几点需要注意。

  • DialogHost是一个ContentControl,内容是窗口的所有内容,对话框应覆盖
  • 使用DialogHost.Show方法时,应该传递对话框的内容,而不是DialogHost本身。 这是您出现周期性错误的根本原因。
  • 通常,您可以在MVVM设置中使用DialogHost.Show,但是您正在使用代码。在这种情况下,您可以使用Routed命令打开对话框,并在关闭对话框时将附加事件回调到代码隐藏中:
<Button
    Command="{x:Static materialDesign:DialogHost.OpenDialogCommand}"
    materialDesign:DialogHost.DialogClosingAttached="DialogClosing"
/>