Caliburn Micro,如何使用ViewModel首先使用ContentControl(或显示“子” ViewModel) [英] Caliburn Micro, How to use ContentControl (or display 'sub' ViewModel) using ViewModel First

查看:151
本文介绍了Caliburn Micro,如何使用ViewModel首先使用ContentControl(或显示“子” ViewModel)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm using MVVM framework Caliburn Micro throughout my application with ViewModel first (or so I thought). However, when I had problems with a dialog using TryClose(true) failing to close it's parent window and stumbled upon this question that perfectly outlined my problem, I'm also getting the "TryClose requires a parent IConductor or a view with a Close method or IsOpen property.":

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

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

However, I'm not exactly sure how to implement the solution. The answer states:


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

Remove the cal:Bind.Model and cal:View.Model bindings...

使用这些绑定结果是一种视图优先的方法,但我当时并没有意识到。以下是我的问题对话框的示例:

Turns out using these bindings is a View-First approach, which I wasn't aware i was doing. Here's a sample of my offending dialog:

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

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

It's just a wrapper with an okay and cancel button for an already existing ViewModel (who's view is resolved by caliburn, hence me thinking I'm doing ViewModel first). If I remove this cal:View.Model binding I do indeed regain the ability to close my dialog box, but I loose all the actual content. I'm using the ContentControl to display things all over my application (in ItemsControls, dialog boxes, pop-ups, etc).

我的问题是,应该首先在Caliburn中在ViewModel中显示ViewModel吗?

My question is, how should I be displaying a ViewModel in a ViewModel first Caliburn?

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

I'm displaying the DialogViewModel (which inherits screen) using the WindowManager like so:

[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);
    }
}


推荐答案

到回答主要问题


我应该如何先在ViewModel中显示ViewModel?

how should I be displaying a ViewModel in a ViewModel first Caliburn?

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

I assume TimeSpanViewModel is a property you have on your ViewModel which has an [Import] (and the ViewModel is exporting itself)? I think that you should change cal:View.Model="{Binding TimeSpanViewModel}" to x:Name="TimeSpanViewModel". Even if this might not solve the issue, it is the right thing to do and Caliburn will make sure it's bound correctly.

我尝试重现您的问题,即使使用你的方式对我有用。因此,为什么它不能像您当前的方式那样起作用,这是一个好问题(第二个问题)。

I tried to reproduce your issue, but even using your way it worked for me. So why it doesn't work the way you are currently doing it, is a good (second) question.

最大的问题可能是您的AppWindowManager,如果窗口在其中创建的内容未通过正确的Caliburn代码,因此无法正确绑定。由于缺少许多代码,我什至不确定 AppViewModel内容{组; } 在那里,大多数情况下我都可以推测。您是否尝试使用默认的WindowManager实现,只是看它是否可以工作?

The biggest problem might be your AppWindowManager, if the window you create in there doesn't go through the correct Caliburn code it will not be correctly bound. As there is a lot of code missing, I'm not even sure what AppViewModel Content { get; set; } is doing there, mostly I can just speculate. Did you try to use the default WindowManager implementation, just to see if it works with that?

这篇关于Caliburn Micro,如何使用ViewModel首先使用ContentControl(或显示“子” ViewModel)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆