本文介绍了MVVM 灯光 &WPF - 将窗口的多个实例绑定到 ViewModel的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在 MVVM 中处理我的第一个项目,并且我选择使用 MVVM Light Toolkit.我有一个 GameViewModel 来处理我游戏主屏幕上的业务.我需要找出如何在执行命令时使用 Adventurer 的实例作为参数打开一个新窗口 (AdventurerView),并将其绑定到 AdventurerViewModel,并显示和返回数据.此窗口的实例将经常打开和关闭.我已经坚持了几天了,这让我发疯了.我想学习如何以对 MVVM 友好的方式执行此操作,最好使用 MVVM Light 或纯 XAML 提供的工具.

I am working on my first project in MVVM and I've chosen to use the MVVM Light Toolkit. I have a GameViewModel that handles business on the main screen of my game. I need to find out how to open a new window (AdventurerView) with an instance of Adventurer as a parameter when a command is executed, have it bound to AdventurerViewModel, and display and return data. Instances of this window will be opened and closed frequently. I have been stuck on this for a couple of days now and it's driving me crazy. I would like to learn how to do this in an MVVM-friendly way, preferably with the tools provided by MVVM Light or pure XAML.

我尝试过使用 MVVM Light 的 ViewModelLocator 但由于 AdventurerView 是一个窗口,所以它无法工作;它说不能把窗口放在一个样式中",尽管程序仍然可以编译和运行.有什么我可以改变的东西吗?还是有另一种方法可以在 XAML 中绑定它们?或者完全是另一种方法?我真的很想能够继续前进.我也尝试过使用 MVVM Light 的 messenger 无济于事(它仍然没有解决 View/ViewModel 问题).

I've tried using MVVM Light's ViewModelLocator but since AdventurerView is a window it won't work; it says "Can't put a Window in a Style", though the program still compiles and runs. Could there be something I could change to make that work? Or is there another way to bind them in XAML? Or another approach entirely? I would really love to be able to move on from this. I have also tried using MVVM Light's messenger to no avail (which still doesn't tackle the View/ViewModel issue).

我只需要能够创建一个绑定到 AdventurerViewModel 的窗口并显示/返回适当的数据.

I just need to be able to create a window that is bound to AdventurerViewModel and display/return the appropriate data.

AdventurerView.xaml 目前处于默认状态,但我觉得如果我能绑定可能有帮助的适当数据 (DataContext).

AdventurerView.xaml is in its default state at the moment, but I feel that if I could bind the appropriate data that might help (DataContext).

AdventurerViewModel 也很简单

AdventurerViewModel is pretty bare-bones as well

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:

App.xaml with the non-working DataTemplate at the bottom:

<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 中的命令有望使这一切发生(消息框只是确认命令正在触发):

The command in GameViewModel that will hopefully make this all happen (the messagebox just confirms that the command is firing):

    private void ExecuteShowAdvCommand(Adventurer adv)
    {
        System.Windows.MessageBox.Show(adv.Name);
    }

我真的不知道还能包括什么.

I don't really know what else to include.

推荐答案

好的,我整理了一个演示,希望能让您更轻松 下载链接

Ok I put together a demo that should make this hopefully easier for you Download Link

功能:

  • 总共 3 个窗口(MainWindowModalWindowNonModalWindow)
  • MainWindow 有一个 TextBox 你可以输入任何你想要的东西.
  • 顶部的 2 个按钮将相应地打开模态/非模态窗口
  • 每个窗口在打开时都会在其中的 TextBlock 中显示 MainWindow 的 TextBox 中的消息.
  • 在每个窗口中,您可以勾选一个 CheckBox 以更新 MainWindow 结果文本块中的值(对于模态窗口,当模态窗口关闭时,这将启动.对于非模态变化可以尽快看到)
  • 3 Windows in Total (MainWindow, ModalWindow, NonModalWindow)
  • MainWindow has a TextBox you can type whatever you want into.
  • 2 buttons on the top will open the Modal / NonModal Window accordingly
  • Each window when opened will display the message that was in MainWindow's TextBox in a TextBlock inside them.
  • In each window you can tick a CheckBox to update the value in result's textblock in MainWindow (For the Modal Window this will kick in when modal window is closed. For NonModal changes can be seen asap)

功能就是这样,

概念:

  • 使用 SimpleIoC 注册多个 VM,并使用 GetInstance(...) 请求它们.
  • 使用自定义消息类型的 Messenger 类OpenWindowMessage
  • 从父虚拟机打开模态/非模态窗口,遵守 MVVM 原则
  • 在窗口之间传递数据(仅在 NonModal 中显示)
  • Registering Multiple VM's with the SimpleIoC and using GetInstance(...) to request them out.
  • Messenger class usage with a custom message type OpenWindowMessage
  • Opening Modal / Non Modal Windows from a parent VM staying true to the MVVM principles
  • Passing data between windows(just shown in NonModal)

重要提示:- 本示例中用于从模态窗口设置非 DP DialogResult 的方法不是 MVVM 友好的,因为它使用代码隐藏在 DialogResult 属性上设置 >Window.Closing应该避免的事件(如果需要可测试").我的首选方法有点长,并且有很好的文档记录 这里(问题和答案的混合).这就是为什么我为了这个示例而忽略了它.

Important Note: - The method used in this example to set the non DP DialogResult from the modal window is not MVVM friendly cos it uses code-behind to set the DialogResult property on a Window.Closing event which should be avoided(If needing to be "testable"). My preferred approach is a bit long and is very well documented HERE(Mixture of question and answer). Hence why I ignored it for the sake of this sample.

这篇关于MVVM 灯光 &amp;WPF - 将窗口的多个实例绑定到 ViewModel的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-07 09:36