我正在开发我在MVVM中的第一个项目,并且我选择使用MVVM Light Toolkit。我有一个GameViewModel
来处理游戏主屏幕上的业务。我需要了解如何在执行命令时将AdventurerView
实例作为参数打开一个新窗口(Adventurer
),将其绑定到AdventurerViewModel
,并显示并返回数据。此窗口的实例将经常打开和关闭。我已经被困在这几天了,这让我发疯了。我想学习如何以MVVM友好的方式执行此操作,最好使用MVVM Light或纯XAML提供的工具。
我尝试过使用MVVM Light的ViewModelLocator
,但由于AdventurerView
是一个窗口,它不起作用;虽然程序仍在编译和运行,但它说“不能把窗口放在一个样式中”。我可以改变一些东西让它起作用吗?或者是否有另一种方法在XAML中绑定它们?或完全是另一种方法?我真的很想能够继续前进。我也试过使用MVVM Light的信使无效(仍然没有解决View / ViewModel问题)。
我只需要能够创建一个绑定到AdventurerViewModel
的窗口并显示/返回相应的数据。
AdventurerView.xaml目前处于默认状态,但我觉得如果我可以绑定可能有用的相应数据(DataContext)。
AdventurerViewModel也是非常简单的
class AdventurerViewModel : ViewModelBase
{
#region Members
private Adventurer _adv;
#endregion
#region Properties
public Adventurer Adv
{
get { return _adv; }
set { _adv = value; }
}
#endregion
#region Construction
public AdventurerViewModel(Adventurer adv)
{
this._adv = adv;
}
#endregion
}
App.xaml,底部是非工作的DataTemplate:
<Application StartupUri="MainWindow.xaml"
xmlns:views="clr-namespace:AoW.Views"
xmlns:vm="clr-namespace:AoW.ViewModels"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="AoW.App"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Application.Resources>
<vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" />
<DataTemplate DataType="{x:Type vm:GameViewModel}">
<views:GameView />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:TitleViewModel}">
<views:TitleView />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:AdventurerViewModel}">
<views:AdventurerView />
</DataTemplate>
</Application.Resources>
</Application>
GameViewModel
中的命令,希望能够完成这一切(消息框只是确认命令正在激活):
private void ExecuteShowAdvCommand(Adventurer adv)
{
System.Windows.MessageBox.Show(adv.Name);
}
我真的不知道还包括什么。
答案 0 :(得分:23)
好的,我整理了一个演示版,可以让您更加轻松Download Link
<强>功能强>
MainWindow
,ModalWindow
,NonModalWindow
)MainWindow
有TextBox
您可以输入任何内容。TextBox
内TextBlock
内的消息。CheckBox
以更新MainWindow
中结果文本块中的值(对于模态窗口,当模态窗口关闭时,这将启动。对于非模态更改,可以看到asap )这就是功能性,
<强>概念强>
SimpleIoC
注册多个VM并使用GetInstance(...)
将其请求退出。OpenWindowMessage
重要提示:
- 此示例中用于从模态窗口设置非DP DialogResult
的方法不是MVVM友好的,因为它使用代码隐藏在DialogResult
事件上设置Window.Closing
属性<强>应该要避免(如果需要“可测试”)。我的首选方法有点长,并且有很好的记录HERE(问答的混合)。因此,为什么我为了这个样本而忽略了它。
答案 1 :(得分:1)
跟进Viv,我修改了示例以包含打开窗口而不使用后面的代码的示例。
我正在使用ViewModelLocator单例和一个静态方法来预告视图模型和窗口以及数据上下文而不是后面的代码。
Blog Post with Details. 让我知道哪种方法更可取。我不喜欢使用背后的代码,但可能会有专业人士和骗局我不知道。