Caliburn Micro,如何使用ViewModel首先使用ContentControl(或显示“子” ViewModel) [英] Caliburn Micro, How to use ContentControl (or display 'sub' ViewModel) using ViewModel First
问题描述
我首先在整个应用程序中将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屋!