Silverlight MVVM灯、Windows Phone、View&;页面之间的ViewModel导航
我有一个页面,您基本上可以选择一组选项(配置),然后转到下一个页面,在那里您可以做一些事情Silverlight MVVM灯、Windows Phone、View&;页面之间的ViewModel导航,silverlight,windows-phone-7,mvvm,Silverlight,Windows Phone 7,Mvvm,我有一个页面,您基本上可以选择一组选项(配置),然后转到下一个页面,在那里您可以做一些事情 使用MVVM Light工具包,我有一个绑定到第一页视图的viewmodel。当用户点击一个按钮时,它会重定向到另一个视图,即第二页 i、 e: page2comand=newdelegatecommand((obj)=> Send(新Uri(“/dostufview.xaml”,UriKind.Relative), Common.CommonResources.GoToDoStuffRequest});
使用MVVM Light工具包,我有一个绑定到第一页视图的viewmodel。当用户点击一个按钮时,它会重定向到另一个视图,即第二页 i、 e:
page2comand=newdelegatecommand((obj)=>
Send(新Uri(“/dostufview.xaml”,UriKind.Relative),
Common.CommonResources.GoToDoStuffRequest});
问题是,第二个视图的viewmodel(在我看来)在构造函数中有几个参数,这些参数基本上是第一页上设置的配置的依赖项
i、 e:
public DoStuffViewModel(ICollection<Note> availableNotes, SoundMappers soundType)
{
}
public DoStuffViewModel(ICollection可用节点,声音映射器声音类型)
{
}
问题就在这里。。如何使用用户在第1页上动态选择的数据实例化viewmodel?我不能使用MVVM light提供的ViewModelLocator模式,因为这些ViewModel没有任何依赖项,它们只是它们自己(或者它们可以从数据库、文件或其他任何地方检索数据,但它们没有任何动态输入数据)。我可以通过视图的构造函数来实现,在那里实例化viewmodel,并将新创建的viewmodel分配给视图的数据源,但我认为这样做不太好。
建议?我看到您使用Messenger类发送消息,因此您熟悉MVVM灯光下的消息。您必须定义自己的消息类型,该类型应接受第1页中的参数:
public class Page2ViewModelCreateMessage : MessageBase
{
public ICollection<Note> AvailableNotes{get;set;}
public SoundMappers SoundType{get;set;}
public Page2ViewModelCreateMessage ()
{
}
public Page2ViewModelCreateMessage(ICollection<Note> availableNotes, SoundMappers soundType)
{
this.AvailableNotes = availableNotes;
this.SoundType = soundType;
}
}
在第2页,您必须注册接收Page2ViewModelCreateMessage类型的消息:
Messenger.Default.Register<Page2ViewModelCreateMessage>(this, OnPage2ViewModelCreateMessage);
..
public void OnPage2ViewModelCreateMessage(Page2ViewModelCreateMessage message)
{
var page2ViewModel = new Page2ViewModel(messsage.AvailableNotes, message.SoundType);
}
Messenger.Default.Register(此,在第2页ViewModelCreateMessage上);
..
Page2ViewModelCreateMessage上的公共无效(Page2ViewModelCreateMessage)
{
var page2ViewModel=新的page2ViewModel(message.AvailableNotes,message.SoundType);
}
如您所见,为了更加清晰,我已将DoStuffViewModel替换为Page2ViewModel
我希望这对你有帮助
注意:我不保证代码会像在记事本中写的那样工作。我这样做的方式是通过接口拥有一个ViewModels都知道的中央控制器类。然后我将状态设置为该状态,然后让手机为我执行导航。然后,每个ViewModel查询该中心类所需的状态 这对我有很多好处:
- 它允许我使用非静态视图模型
- 我可以使用Ninject注入控制器类的具体实现,并将其限定为单例
- 最重要的是,在进行逻辑删除时,我只需要获取当前的ViewModel和controller类
public interface IController
{
Foo SelectedFoo { get; }
}
public class ViewModel
{
private IController _controller;
public ViewModel(IController controller)
{
_controller = controller;
}
private void LoadData()
{
// Using selected foo, we load the bars.
var bars = LoadBars(_controller.SelectedFoo);
}
}
您可以使用PhoneApplicationService字典保存从第一个事件导航时所需的数据,并在导航到第二个页面时对其进行解析。也可以在ViewModels中使用该数据。 大概是这样的:
PhoneApplicationService.Current.State["DatatFromFirstPage"] = data;
导航到第二页时:
if (PhoneApplicationService.Current.State.ContainsKey("DatatFromFirstPage"))
{
var dataUsedOnSeconPage= PhoneApplicationService.Current.State["DatatFromFirstPage"];
}
您可以在整个应用程序中全局使用此数据尽管您正在注入依赖项,但您的ViewModels不应该从其他地方获取数据,因为这会破坏VM的分离性和可测试性。我们通常让控制器管理虚拟机并将值填充到其中,而不是让虚拟机从外部拖入值。虚拟机应该尽可能无知。只是一个意见。请随意忽略:)让ViewModel需要一些东西是有效的。我看不出给ViewModel提供一个信息源接口与ViewModel依赖之前收到的消息之间有什么区别。至于测试,接口可以模拟。。。因此,它是完全可测试的。+1消息传递是分离ViewModel的一种很好的一致方式,尽管值得说明的是,这是许多可用选项之一。您好。如果我没有错的话,OnPage2ViewModelCreateMessage方法在Page2View上。最后,视图将创建viewmodel,并将其分配给它的DataSource属性。这是正确的吗?我不确定视图是否应该创建viewmodel,尽管消息传递系统确实是发送参数进行创建的系统,而不是实例化参数的视图。嗨,Daniel。你没有错。OnPage2ViewMNodelCreateMessage方法位于Page2View上,并在其中创建ViewModel。另一个选项是对ViewModel使用ViewModelLocator并将其引用到View.DataContext。然而,第一个选项并没有“如此”地破坏MVVM模式。
PhoneApplicationService.Current.State["DatatFromFirstPage"] = data;
if (PhoneApplicationService.Current.State.ContainsKey("DatatFromFirstPage"))
{
var dataUsedOnSeconPage= PhoneApplicationService.Current.State["DatatFromFirstPage"];
}