C# MVVM灯和;WPF-将窗口的多个实例绑定到ViewModel
我正在从事我在MVVM中的第一个项目,我选择使用MVVM Light Toolkit。我有一个C# MVVM灯和;WPF-将窗口的多个实例绑定到ViewModel,c#,wpf,mvvm,mvvm-light,C#,Wpf,Mvvm,Mvvm Light,我正在从事我在MVVM中的第一个项目,我选择使用MVVM Light Toolkit。我有一个GameViewModel,在我的游戏主屏幕上处理业务。我需要了解如何在执行命令时打开一个新窗口(AdventurerView),并将Adventurer的实例作为参数,将其绑定到AdventurerViewModel,并显示和返回数据。此窗口的实例将经常打开和关闭。这件事我已经坚持了好几天了,快把我逼疯了。我想学习如何以MVVM友好的方式完成这项工作,最好使用MVVM Light或纯XAML提供的工具
GameViewModel
,在我的游戏主屏幕上处理业务。我需要了解如何在执行命令时打开一个新窗口(AdventurerView
),并将Adventurer
的实例作为参数,将其绑定到AdventurerViewModel
,并显示和返回数据。此窗口的实例将经常打开和关闭。这件事我已经坚持了好几天了,快把我逼疯了。我想学习如何以MVVM友好的方式完成这项工作,最好使用MVVM Light或纯XAML提供的工具
我曾尝试使用MVVM Light的ViewModelLocator
,但由于AdventurerView
是一个窗口,因此无法工作;它说“不能把一个窗口放在一个样式中”,尽管程序仍然编译和运行。有什么可以改变的吗?或者有没有其他方法可以在XAML中绑定它们?还是完全另一种方法?我真的很希望能够从这件事开始。我还尝试过使用MVVM Light的messenger,但没有成功(这仍然不能解决视图/视图模型问题)
我只需要能够创建一个绑定到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,底部为非工作数据模板:
<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>
我真的不知道还包括什么。好的,我准备了一个演示,希望能让你更容易 功能:
- 总共3个窗口(
,main窗口
,ModalWindow
)非模态窗口
有一个main窗口
,您可以在其中键入任何内容文本框
- 顶部的2个按钮将相应地打开模态/非模态窗口
- 打开时,每个窗口将在其内部的
中显示主窗口TextBlock
中的消息TextBox
- 在每个窗口中,您可以勾选一个
复选框来更新
main窗口中结果文本块的值(对于模式窗口,这将在模式窗口关闭时生效。对于非模式更改,可以尽快查看)
- 使用
注册多个VM,并使用SimpleIoC
请求它们退出GetInstance(…)
- 自定义消息类型的Messenger类用法
OpenWindowMessage
- 从父虚拟机打开模式/非模式窗口,遵守MVVM原则
- 在窗口之间传递数据(仅以非模式显示)
-本例中用于从模式窗口设置非DP
DialogResult
的方法对MVVM不友好,因为它使用代码隐藏在窗口上设置DialogResult
属性。关闭事件时应避免(如果需要“可测试”)。我喜欢的方法有点长,并且有很好的文档记录(问答混合)。因此,为了这个示例,我忽略了它。继Viv之后,我修改了这个示例,以包含一个打开窗口而不使用代码隐藏的示例
我正在使用ViewModelLocator单例和一个静态方法,该方法可以更新viewmodel和窗口以及数据上下文,而不是隐藏代码
让我知道哪种方法更可取。我不喜欢使用代码隐藏,但我可能会遗漏一些正反两方面的内容。您是否使用了mvvm light附带的Messenger
?简单来说,首先不要在主窗口的xaml中将新窗口声明为DataTemplate
。当您需要创建您的AdventureView
时,您需要在GameViewModel
中执行以下操作:向Main窗口发送消息,该窗口应在代码隐藏中注册并接收此消息,创建AdventureView
并相应地调用Show()
或ShowDialog()
SimpleIoC
应该为AdventureViewModel
处理VM的创建。这对你有意义吗?显示了使用MVVM灯光打开新窗口的示例。做同样的事情还有其他几种选择,但这应该是一个好的开始。现在在发送这些“消息”时您可以传递您选择的任何参数,使传递参数infoas变得简单,以获得响应,这取决于您如何获取数据,如果是一个对话框,您可以调用ShowDialog,它将是模态的,并检查其返回值,或者再次使用Messenger
将结果发送回GameViewModel
谢谢。我来看看。我目前正在探索Messenger,尽管我从未成功使用过它。我仍然不确定如何将对象传递给新的view vie Messenger。我还没有看到一个很好的例子。谢谢你这么令人难以置信的回答。我想我现在差不多可以用了。当我试图打开新窗口时,出现了一个错误——“发生了XAMLParseException”,指向模式窗口中有关DataContext的行,我不知道它为什么这样做。现在我不知道这些行是如何出现的。我删除了它,现在没有任何错误,但是窗口没有显示。我所要做的就是调用.Show()-它现在可以正常工作了。很遗憾,我只能对这个答案投一次赞成票。最后一件事:如果我打开第二个窗口,它会将第一个窗口中的信息更改为第二个窗口中的信息。有没有办法防止这种情况?再次感谢你这么好的回答!我的糟糕,电话秀()
private void ExecuteShowAdvCommand(Adventurer adv)
{
System.Windows.MessageBox.Show(adv.Name);
}