MVVM灯&WPF -将一个窗口的多个实例绑定到一个视图模型
本文关键字:一个 实例 绑定 模型 视图 窗口 WPF MVVM | 更新日期: 2023-09-27 18:17:22
我正在做我在MVVM中的第一个项目,我选择使用MVVM Light Toolkit。我有一个GameViewModel
在游戏的主屏幕上处理业务。我需要找出如何打开一个新的窗口(AdventurerView
)与Adventurer
的实例作为参数,当一个命令被执行,有它绑定到AdventurerViewModel
,并显示和返回数据。此窗口的实例将频繁地打开和关闭。我已经被这个问题困了好几天了,快把我逼疯了。我想学习如何以MVVM友好的方式做到这一点,最好使用MVVM Light或纯XAML提供的工具。
我试过使用MVVM光的ViewModelLocator
,但由于AdventurerView
是一个窗口,它不会工作;它说"不能将窗口设置为样式",尽管程序仍然可以编译并运行。有什么我可以改变的地方吗?或者在XAML中是否有其他方法来绑定它们?或者完全采用另一种方法?我真的很希望能放下这一切。我也尝试过使用MVVM光的信使无济于事(这仍然不能解决视图/ViewModel问题)。
我只需要能够创建一个绑定到AdventurerViewModel
和显示/返回适当的数据的窗口。
AdventurerView。xaml目前处于默认状态,但我觉得如果我可以绑定适当的数据(DataContext),可能会有所帮助。
adventerviewmodel也是非常简单的
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
}
应用程序。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);
}
我真的不知道还应该包括什么
好的,我准备了一个演示,希望能让你们更容易理解。
功能:
- 3个Windows (
MainWindow
,ModalWindow
,NonModalWindow
) -
MainWindow
有一个TextBox
,你可以输入任何你想要的。 - 顶部的两个按钮将相应地打开模态/非模态窗口
- 当打开每个窗口时,将显示主窗口的
TextBox
中的消息在其中的TextBlock
中。 - 在每个窗口中,您可以勾选
CheckBox
来更新MainWindow
中结果文本块中的值(对于模态窗口,这将在模态窗口关闭时启动)。对于非模态的更改可以尽快看到)
这就是它的功能,
概念:
- 使用
SimpleIoC
注册多个VM,并使用GetInstance(...)
请求它们退出 - 自定义消息类型
OpenWindowMessage
的信使类使用情况 - 从父虚拟机打开模态/非模态窗口,遵循MVVM原则
- 在窗口之间传递数据(在NonModal中显示)
重要提示:-本例中使用的从模态窗口设置非DP DialogResult
的方法不是MVVM友好的,因为它使用代码隐藏来设置Window.Closing
事件上的DialogResult
属性,应该避免(如果需要"可测试")。我更喜欢的方法是有点长,并且在这里有很好的记录(问题和答案的混合)。因此,为了这个示例,我忽略了它。
在Viv之后,我修改了示例,以包含一个不使用后面代码打开窗口的示例。
示例项目在这里。
我利用ViewModelLocator单例与一个静态方法,新闻的视图模型和窗口和数据上下文,而不是背后的代码。
包含详细信息的博客文章。让我知道哪种方法更可取。我不喜欢使用后面的代码,但是可能有我遗漏的优点和缺点。