C# WPF&;MVVM灯光-将对象传递到新窗口
我想学习最正确的方法:我的GameView中有一个Listview,它绑定到一个C# WPF&;MVVM灯光-将对象传递到新窗口,c#,wpf,xaml,mvvm,mvvm-light,C#,Wpf,Xaml,Mvvm,Mvvm Light,我想学习最正确的方法:我的GameView中有一个Listview,它绑定到一个ObservableCollection。双击单元格后,我需要一个新窗口(或其他更合适的窗口)根据单元格打开并显示有关正确的冒险家的数据。到目前为止我还没能做到。这就是我到目前为止所做的(虽然不多,但我尝试过的都没有成功) GameView.xaml中我的列表视图中的触发器/命令 <i:Interaction.Triggers> <i:EventTrigger EventName="Mous
ObservableCollection
。双击单元格后,我需要一个新窗口(或其他更合适的窗口)根据单元格打开并显示有关正确的冒险家的数据。到目前为止我还没能做到。这就是我到目前为止所做的(虽然不多,但我尝试过的都没有成功)
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>
AdventurerView:
public partial class AdventurerView : Window
{
Adventurer adv;
public AdventurerView(Adventurer adv)
{
this.adv = adv;
InitializeComponent();
}
}
现在我需要弄清楚如何在XAML、数据绑定等方面实现这一点
更新:…然后我意识到这完全违背了MVVM。有人有什么建议吗
更新:MVVM Light的messenger能帮我吗?我一直在修补它,但还没有让它工作
更新:这个问题仍然悬而未决。我尝试了棱镜方法,但棱镜和MVVM灯光之间存在一些冲突,导致了更多的麻烦。我愿意接受任何与MVVM Light和MVVM模式兼容的想法
更新:此外,如果可能的话,我想以一种可以同时存在多个弹出窗口的方式来完成这项工作。在类似的情况下,我使用了MvvmLight的Messenger,它工作得非常好。双击后,从viewmodel发送一条消息,其中包含要传递的实体。您需要在某个地方注册以接收消息,具体取决于您如何设置要激活的视图和视图模型
您可以注册以在MainPage.xaml中接收消息,然后直接将实体传递给视图的构造函数,或者通过接口访问视图的DataContext以传递实体,具体取决于您是否在子窗口中使用viewmodel。例如
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);
}
公共接口IEntityViewModel其中T:class
{
无效SetCurrentEntity(T实体);
}
viewmodel将实现此界面:
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.
}
}
公共类AdventurerViewModel:IEntityViewModel
{
公共无效SetCurrentEntity(冒险家实体)
{
//根据您的需要,对实体执行您需要的操作,
//您可以保持它的完整性,以防编辑被取消
//复印一份。
}
}
正如您所指出的,正确的MVVM不会实例化视图并通过构造函数传递视图模型。最好将ViewModel绑定到视图,有许多不同的方法
出现的一种模式是被称为“屏幕导体”的概念。这是一个顶级ViewModel或控制器,用于处理表示主窗口的ViewModel。同样,有许多不同的方法可以做到这一点。例如,ViewModel可能引发屏幕导体处理的标准.net事件。您可以使用Caliburn.Micro的EventAggregator或MVVM Light的Messenger等消息传递系统。我认为MEFedMVVM也有一个事件聚合器来实现这一点
Caliburn.Micro还有一个WindowManager,您可以将它传入ViewModel,让它自动找到相应的视图并管理窗口的生命周期
有很多选择。找到最适合您的方案。这是Prism的InteractionRequest的一个很好的例子。实际上,在ViewModel上有一个InteractionRequest对象,双击(在双击命令中)时会引发该对象。视图上有一个操作,用于处理引发的事件并显示新视图。将新的ViewModel传递给该交互,这就是将显示的窗口的DataContext。让你开始。这就是我在应用程序中显示所有子窗口的方式。[…]正确的MVVM不会实例化视图并通过构造函数传递视图模型。-嗯,为什么这不合适?我知道View
和ViewModel
之间的唯一限制是,视图
可以知道视图模型
,但是视图模型
不能知道视图
。正确的mvvm将视图与视图模型解耦,这样它们之间就没有直接的依赖关系。如果某个实体引用其属性(绑定),那么它如何与该实体解耦这就是WPF的威力——它是基于属性的绑定,而不是特定类型的绑定,这意味着您可以用这些属性绑定任何对象,并使其在视图中工作。这看起来是我在这种情况下采取的最佳途径。一旦我成功了,我会接受你的回答。这对我来说都是新的,所以可能需要一点时间。@DennisE是的,我花了一点时间来启动和运行。好在你不需要一个成熟的Prism应用程序;您可以只使用InteractionRequest对象。祝你好运,如果你有任何问题,请告诉我。你发布的链接中的代码充满了错误,无法编译,但我确实找到了这个示例,它似乎完成了我需要的一切:-该示例包含许多类,我想知道我需要这些类来实现我正在尝试的目标(用于显示有关对象的信息,并可能将更新的数据发送回).如果你不介意帮我把这个从地上拿开,也许我们可以开始聊天?我刚刚下载了相同的示例,它对我来说很好。你有什么错误?我现在不能聊天。检查参考资料,确保它找到了所有内容。下载的内容包括你需要的所有文件。你提供给我的链接是类似,但我认为更复杂。我得到了您发布到工作中的示例(我刚从NuGet获得了Prism),它看起来很有希望。我今天晚些时候将开始将Prism集成到我的项目中。什么是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.
}
}