WPF和MVVM光-通过对象到新窗口

本文关键字:新窗口 窗口 对象 MVVM -通 WPF | 更新日期: 2023-09-27 18:17:02

我想学习最正确的方法:我在GameView中有一个绑定到ObservableCollection<Adventurer>的Listview。双击单元格后,我需要一个新窗口(或者其他更合适的东西)来打开并显示根据单元格正确的Adventurer的数据。到目前为止我还没能做到。这是我到目前为止所做的(不多,但我尝试过的都没有成功)。

GameView.xaml中我的ListView中的trigger/命令

<i:Interaction.Triggers>
    <i:EventTrigger EventName="MouseDoubleClick">
        <cmd:EventToCommand Command="{Binding Mode=OneWay, Path=ShowAdvCommand}"
                            CommandParameter="{Binding ElementName=AdvListView, 
                                                       Path=SelectedItem}"
                            PassEventArgsToCommand="True" />
    </i:EventTrigger>
</i:Interaction.Triggers>

和GameViewModel.cs

中的命令
ShowAdvCommand = new RelayCommand<Adventurer>(p =>
{
    System.Windows.MessageBox.Show(p.Name);
});

MessageBox只是在那里确认Eventtocommand正在工作。

我基本上需要一个容器,它将在双击Listview单元格后将正确的Adventurer作为参数,并允许我显示特定于该实例的数据。我也更愿意坚持使用对mvvm友好的东西。

如有任何建议,不胜感激。

更新:我可能已经取得了一点进展:

GameViewModel:

ShowAdvCommand = new RelayCommand<Adventurer>(p =>
{
    AdventurerView adv = new AdventurerView(p);
    adv.Show();
});

AdventurerView:

public partial class AdventurerView : Window
{
    Adventurer adv;
    public AdventurerView(Adventurer adv)
    {
        this.adv = adv;
        InitializeComponent();
    }
}

现在我需要弄清楚如何使这个工作在XAML,数据绑定等。

更新:…然后我意识到这完全违背了MVVM。有人有什么建议吗?

更新: MVVM Light的信使会帮我吗?我一直在修修补补,但还没有让它工作。

更新:这个问题还没有解决。我尝试了Prism方法,但Prism和MVVM Light之间存在一些冲突,造成的麻烦超过了它的价值。我对任何与MVVM Light和MVVM模式兼容的想法都持开放态度。

更新:此外,如果可能的话,我想在多个弹出窗口可以同时存在的方式做到这一点。

WPF和MVVM光-通过对象到新窗口

在类似的情况下,我使用了MvvmLight的Messenger,它工作得非常好。双击后,从视图模型发送一条消息,其中包含要传递的实体。您将需要在某个地方注册以接收消息,这取决于您如何设置要激活的视图和视图模型。

您可以在主页中注册以接收该消息。或者直接将实体传递给视图的构造函数,或者通过接口访问视图的DataContext来传递实体,这取决于你是否在子窗口中使用视图模型。例如

AdventurerView adv = new AdventurerView();
IEntityViewModel vm = adv.DataContext as IEntityViewModel;
vm.SetCurrentEntity(entity);
adv.Show();

IEntityViewModel可能如下所示:

public interface IEntityViewModel<T> where T : class
{
    void SetCurrentEntity(T entity);
}

视图模型将实现以下接口:

public class AdventurerViewModel : IEntityViewModel<Adventurer>
{
    public void SetCurrentEntity(Adventurer entity)
    {
        // Do what you need to with the entity - depending on your needs, 
        // you might keep it intact in case editing is cancelled, and just
        // work on a copy.
    }
}

正如您所指出的,适当的MVVM不会实例化视图并通过构造函数传递视图模型。你最好将ViewModel绑定到View,有许多不同的方法可以做到这一点。

已经出现的一种模式是一个被称为"屏幕导体"的概念。这是一个顶层的ViewModel或控制器,它处理代表主窗口的ViewModel。同样,有很多不同的方法。例如,ViewModel可以引发一个由Screen Conductor处理的标准.net事件。你可以使用像Caliburn这样的消息传递系统。Micro的EventAggregator或MVVM Light的Messenger。我认为MEFedMVVM也有一个事件聚合器来完成这个任务。

这份原稿。Micro也有一个WindowManager,你可以在你的ViewModel中传递它,让它自动找到相应的视图并管理窗口的生命周期。

有很多选项。找一个最适合你的

这是Prism的InteractionRequest的一个很好的例子。本质上,你在你的ViewModel上有一个InteractionRequest对象,当你双击(在你的双击命令中)时,你会引发这个对象。视图上有一个Action,用于处理引发事件并显示新视图。你传递一个新的ViewModel给那个交互那是将要显示的窗口的DataContext。这里有一些好的信息可以帮助你开始。这是我在我的应用程序中显示所有子窗口的方式。