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

我真的不知道还应该包括什么

MVVM灯&WPF -将一个窗口的多个实例绑定到一个视图模型

好的,我准备了一个演示,希望能让你们更容易理解。

功能:

  • 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单例与一个静态方法,新闻的视图模型和窗口和数据上下文,而不是背后的代码。

包含详细信息的博客文章。让我知道哪种方法更可取。我不喜欢使用后面的代码,但是可能有我遗漏的优点和缺点。