繁体   English   中英

MVVM Light&WPF - 将Window的多个实例绑定到ViewModel

[英]MVVM Light & WPF - Binding Multiple instances of a Window to a ViewModel

我正在研究MVVM中的第一个项目,我选择使用MVVM Light Toolkit。 我有一个GameViewModel可以在我的游戏主屏幕上处理业务。 我需要了解如何在执行命令时将Adventurer实例作为参数打开一个新窗口( AdventurerView ),将其绑定到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);
    }

我真的不知道还包括什么。

好的,我整理了一个演示版本,可以让您更轻松地下载链接

功能:

  • 3总计Windows( MainWindowModalWindowNonModalWindow
  • MainWindow有一个TextBox你可以输入你想要的任何内容。
  • 顶部的2个按钮将相应地打开Modal / NonModal窗口
  • 打开时,每个窗口都会在其中的TextBlock显示MainWindow的TextBox中的消息。
  • 在每个窗口中,您可以勾选一个CheckBox来更新MainWindow中结果文本块中的值(对于模态窗口,这将在模态窗口关闭时启动。对于NonModal更改可以看作asap)

这就是功能,

概念:

  • 注册多个虚拟机与SimpleIoC和使用GetInstance(...)要求他们出去。
  • 具有自定义消息类型OpenWindowMessage Messenger类用法
  • 从父VM中打开Modal / Non Modal Windows,坚持MVVM原则
  • 在窗口之间传递数据(仅在NonModal中显示)

重要说明: - 此示例中用于从模式窗口设置非DP DialogResult的方法不是MVVM友好的因为它使用代码隐藏来设置应该避免的Window.Closing事件上的DialogResult属性(如果需要的话) “可测”)。 我喜欢的方法有点长,在这里有很好的记录(问答的混合)。 因此,为什么我为了这个样本而忽略了它。

跟进Viv,我修改了示例以包含打开窗口而不使用后面的代码的示例。

示例项目在这里。

我正在使用ViewModelLocator单例和静态方法,该方法用于通知viewmodel和window以及Data Context而不是后面的代码。

博客文章详细信息。 让我知道哪种方法更可取。 我不喜欢使用背后的代码,但可能有专业人士和骗子我不见了。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM