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模式兼容的想法都持开放态度。
更新:此外,如果可能的话,我想在多个弹出窗口可以同时存在的方式做到这一点。
在类似的情况下,我使用了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。这里有一些好的信息可以帮助你开始。这是我在我的应用程序中显示所有子窗口的方式。