WPF & MVVM Light-Pass 对象进入新窗口

Jas*_*n D 2 c# wpf xaml mvvm mvvm-light

我想学习最正确的方法来解决这个问题:我的 GameView 中有一个绑定到ObservableCollection<Adventurer>. 双击单元格后,我需要一个新窗口(或其他更合适的窗口)来打开并显示有关Adventurer根据单元格正确的数据。到目前为止我还做不到。这就是我到目前为止所拥有的(并不多,但我尝试过的一切都没有奏效)。

我的 ListView 中的触发器/命令 GameView.xaml

<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>
Run Code Online (Sandbox Code Playgroud)

以及 GameViewModel.cs 中的命令

ShowAdvCommand = new RelayCommand<Adventurer>(p =>
{
    System.Windows.MessageBox.Show(p.Name);
});
Run Code Online (Sandbox Code Playgroud)

MessageBox 只是为了确认 Eventtocommand 正在工作。

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

任何建议将不胜感激。

更新:我可能取得了一些进展:

游戏视图模型:

ShowAdvCommand = new RelayCommand<Adventurer>(p =>
{
    AdventurerView adv = new AdventurerView(p);
    adv.Show();
});
Run Code Online (Sandbox Code Playgroud)

冒险家视图:

public partial class AdventurerView : Window
{
    Adventurer adv;

    public AdventurerView(Adventurer adv)
    {
        this.adv = adv;
        InitializeComponent();
    }
}
Run Code Online (Sandbox Code Playgroud)

现在我需要弄清楚如何在 XAML、数据绑定等中完成这项工作。

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

更新: MVVM Light 的信使会在这里帮助我吗?我一直在修补它,但还没有让它发挥作用。

更新:这个问题仍然悬而未决。我尝试了 Prism 方法,但 Prism 和 MVVM Light 之间存在一些冲突,造成的麻烦多于其价值。我对任何与 MVVM Light 和 MVVM 模式兼容的想法持开放态度。

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

Aly*_*yce 5

在类似的情况下,我使用了 MvvmLight 的 Messenger,而且效果非常好。双击时,从您的视图模型发送一条消息,其中包含您要传递的实体。您需要在某个地方注册才能接收消息,具体取决于您如何设置要激活的视图和视图模型。

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

AdventurerView adv = new AdventurerView();
IEntityViewModel vm = adv.DataContext as IEntityViewModel;
vm.SetCurrentEntity(entity);
adv.Show();
Run Code Online (Sandbox Code Playgroud)

IEntityViewModel可能看起来像下面这样:

public interface IEntityViewModel<T> where T : class
{
    void SetCurrentEntity(T entity);
}
Run Code Online (Sandbox Code Playgroud)

视图模型将实现此接口:

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.
    }
}
Run Code Online (Sandbox Code Playgroud)