Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# MVVM灯和;WPF-将窗口的多个实例绑定到ViewModel_C#_Wpf_Mvvm_Mvvm Light - Fatal编程技术网

C# MVVM灯和;WPF-将窗口的多个实例绑定到ViewModel

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提供的工具

我正在从事我在MVVM中的第一个项目,我选择使用MVVM Light Toolkit。我有一个
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窗口中结果文本块的值(对于模式窗口,这将在模式窗口关闭时生效。对于非模式更改,可以尽快查看)
这就是它的功能性

概念:

  • 使用
    SimpleIoC
    注册多个VM,并使用
    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);
    }