我想学习最合适的方法:我的GameView中有一个Listview绑定到ObservableCollection<Adventurer>
。双击单元格后,我需要一个新窗口(或其他任何更合适的东西),根据单元格打开并显示有关正确Adventurer
的数据。到目前为止,我还没有。这就是我到目前为止所做的事情(它并不多,但我尝试过的任何工作都没有。)
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>
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和MVVM Light之间存在一些冲突,造成了比它值得更多的麻烦。我对任何与MVVM Light和MVVM模式兼容的想法持开放态度。
更新另外,我想以多种弹出窗口可以同时存在的方式执行此操作。
答案 0 :(得分:4)
在类似情况下,我使用过MvvmLight的Messenger,它运行得非常好。双击,从包含要传递的实体的viewmodel发送消息。在某处您需要注册才能接收消息,具体取决于您设置视图的方式和要激活的视图模型。
您可以注册以在MainPage.xaml中接收消息,并将实体直接传递给视图的构造函数,或者通过接口访问视图的DataContext以传递实体,具体取决于您是否使用了viewmodel你的孩子窗口。 E.g。
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);
}
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.
}
}
答案 1 :(得分:0)
正如您所指出的,正确的MVVM不会实例化视图并通过构造函数传递视图模型。你最好将ViewModel绑定到View,并且有很多不同的方法。
已出现的一种模式是称为“屏幕导体”的概念。这是一个顶级ViewModel或控制器,用于处理哪个ViewModel代表主窗口。同样,许多不同的方法来做到这一点。例如,ViewModel可以引发Screen Conductor处理的标准.net事件。您可以使用消息传递系统,如Caliburn.Micro的EventAggregator或MVVM Light的Messenger。我认为MEFedMVVM也有一个事件聚合器来完成这个任务。
Caliburn.Micro还有一个WindowManager,你可以在ViewModel中传递它,让它自动找到相应的View并管理窗口的生命周期。
很多选择。找到最适合你的那个。
答案 2 :(得分:0)
这是Prism的InteractionRequest的一个很好的例子。实质上,您在ViewModel上有一个InteractionRequest对象,当您双击(在双击命令中)时,您会引发该对象。您的视图上有一个Action,用于处理Raised事件并显示新视图。您将新的ViewModel传递给该交互,这是将显示的窗口的DataContext。 Here's some good information让你入门这就是我在应用程序中显示所有子窗口的方式。