等到可视化树完成更新

本文关键字:更新 可视化 | 更新日期: 2023-09-27 18:11:03

我在启动时打开对话框时得到这个错误:Cannot perform this operation while dispatcher processing is suspended.

在应用程序开始时,在窗口顶部打开一个登录对话框窗口,其中包含可切换的内容。我的意思是我有一个窗口,其中的内容得到切换通过设置主窗口上的ViewModel属性。

我没有得到错误,如果我不设置主窗口视图模型,因为它不需要改变视图中的任何东西。

这是MainView,具有可切换的视图模型:

<Window x:Class="WpfProject.Views.Main.MainView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:ViewModels="clr-namespace:WpfProject.ViewModels.Main"
    Title="WpfProject" Height="700" Width="1000"
    Content="{Binding ViewModel}"
    Visibility="{Binding MainWindowVisiblility}"
    xmlns:MvvmDialogs="clr-namespace:MvvmDialogs.Behaviors;assembly=MvvmDialogs"
    MvvmDialogs:DialogBehavior.DialogViewModels="{Binding Dialogs}"
    xmlns:Behaviors="clr-namespace:WpfProject.Behaviors"
    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
>
<i:Interaction.Behaviors>
    <Behaviors:CancelCloseWindowBehavior CloseAction="{Binding CloseAction}"></Behaviors:CancelCloseWindowBehavior>
</i:Interaction.Behaviors>
<i:Interaction.Triggers>
    <i:EventTrigger EventName="Loaded">
        <i:InvokeCommandAction Command="{Binding StartUpProcedureCommand}"></i:InvokeCommandAction>
    </i:EventTrigger>
</i:Interaction.Triggers>
<Window.DataContext>
    <ViewModels:MainViewModel ></ViewModels:MainViewModel>
</Window.DataContext>

交互触发器是执行对话框窗口的操作。

对于对话框窗口,我使用Mark J Feldman处理对话框的方式,可以在这里找到

现在,正如标题中所建议的,我想等到MainViewModel已经改变并更新了视图,在打开对话框窗口之前。

启动程序命令:

private ICommand _StartUpProcedureCommand;
public ICommand StartUpProcedureCommand
{
    get
    {
        return _StartUpProcedureCommand ?? (_StartUpProcedureCommand = new Command(StartUpProcedure));
    }
}
private void StartUpProcedure()
{
    UserLoginDialog();
}
private void UserLoginDialog(IUser user = null)
{
    MainWindowVisiblility = Visibility.Hidden;
    LoginViewModel lvm=new LoginViewModel(user);
    this.Dialogs.Add(lvm);
    if (lvm.Result == null)
        Application.Current.MainWindow.Close();
}

等到可视化树完成更新

尽管Mark写了一篇很长的文章,但他的对话模式在我看来是一个非常丑陋和拙劣的解决方案。

你在UI线程上得到了某种死锁,需要在Dispatcher.BeginInvoke中包装新窗口的显示,以便它被异步执行,并允许调度线程继续处理。

像这样:

Dispatcher.BeginInvoke(new Action(() => new CustomDialogWindow {DataContext = parent.DataContext}.ShowDialog());