Caliburn Micro,如何使用ViewModel首先使用ContentControl(或显示“子” ViewModel)

Joe*_*Joe 5 c# wpf mvvm caliburn.micro

我首先在整个应用程序中将MVVM框架Caliburn Micro与ViewModel一起使用(或者我认为是这样)。但是,当我在使用对话框TryClose(true)无法关闭其父窗口时遇到问题,并且偶然发现了一个完美地概述了我的问题的问题时,我也得到了“ TryClose需要父IConductor或具有Close方法或IsOpen属性的视图。 “:

Caliburn.Micro-ShowDialog()如何关闭对话框?

但是,我不确定如何实现该解决方案。答案指出:

删除cal:Bind.Model和cal:View.Model绑定...

事实证明,使用这些绑定是一种“视图优先”的方法,我当时并不知道我在做什么。这是我的令人讨厌的对话框的示例:

<UserControl ... Height="206" Width="415">
    <Grid Margin="20">
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="AUTO" />
        </Grid.RowDefinitions>
        <Grid Grid.Row="1">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>
            <Button x:Name="Okay" Content="Okay" Width="100" Grid.Column="0" HorizontalAlignment="Center" VerticalAlignment="Center" />
            <Button x:Name="Cancel" Content="Cancel" Width="100" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Center" />
        </Grid>
        <ContentControl cal:View.Model="{Binding TimeSpanViewModel}"/>
    </Grid>
</UserControl>
Run Code Online (Sandbox Code Playgroud)

它只是一个包装,它具有一个已经存在的ViewModel(可以通过caliburn解析其视图)的“确定”和“取消”按钮,因此我想我首先要做ViewModel。如果删除此cal:View.Model绑定,则确实可以恢复关闭对话框的功能,但是我丢失了所有实际内容。我正在使用ContentControl在我的应用程序中显示所有内容(在ItemsControls,对话框,弹出窗口等中)。

我的问题是,我应该如何先在ViewModel中显示ViewModel?

编辑:我正在使用WindowManager显示DialogViewModel(继承屏幕),如下所示:

[Export(typeof(IWindowManager))]
public class AppWindowManager : MetroWindowManager, IDialogManager
{
    AppViewModel Content { get; set; }

    public AppWindowManager()
    {

    }

    public override MetroWindow CreateCustomWindow(object view, bool windowIsView)
    {
        if (windowIsView)
        {
            return view as MainWindowContainer;
        }

        MainWindowContainer window = new MainWindowContainer();
        //{
        window.Content = view;
        //};

        return window;
    }

    public override bool? ShowDialog(object rootModel, object context = null, IDictionary<string, object> settings = null)
    {
        Window window = CreateWindow(rootModel, true, context, settings);

        return window.ShowDialog();
    }

    public object ShowCustomDialog(object rootModel, string title, bool showWindowsOptions = true)
    {
        dynamic settings = new ExpandoObject();
        settings.Title = title;
        settings.ShowCloseButton = showWindowsOptions;
        settings.ShowMaxRestoreButton = showWindowsOptions;
        settings.ShowMinButton = showWindowsOptions;
        settings.SizeToContent = SizeToContent.WidthAndHeight;
        return ShowDialog(rootModel, null, settings);
    }

    public ILoadingDialogViewModel CreateLoadingDialogManager()
    {
        return new LoadingDialogViewModel(this);
    }
}
Run Code Online (Sandbox Code Playgroud)

Rob*_*rom 3

回答主要问题

我应该如何在 ViewModel 第一个 Caliburn 中显示 ViewModel?

我假设TimeSpanViewModel你的 ViewModel 上有一个属性,它有一个[Import](并且 ViewModel 正在导出自身)?我认为你应该cal:View.Model="{Binding TimeSpanViewModel}"改为x:Name="TimeSpanViewModel". 即使这可能无法解决问题,但这也是正确的做法,Caliburn 将确保其正确绑定。

我尝试重现您的问题,但即使使用您的方式它也对我有用。那么,为什么它不能按照您当前的方式工作,这是一个很好的(第二个)问题。

最大的问题可能是您的 AppWindowManager,如果您在其中创建的窗口没有经过正确的 Caliburn 代码,它将无法正确绑定。由于缺少很多代码,我什至不确定AppViewModel Content { get; set; }那里在做什么,大多数情况下我只能推测。您是否尝试使用默认的 WindowManager 实现,只是为了看看它是否适用?