有没有办法从 ViewModel 中调用 Navigate?
我有一个 Silverlight 4 项目,它显示一个图表和一些按钮,允许用户更改图表的日期范围。日期范围也可以通过查询字符串参数传入 - 类似于 http://myserver/MySilverlightPage/ #?DateRange=OneMonth - 当用户单击按钮时,我也想更新 Url。
我知道执行此操作的方法是调用 this.NavigationService.Navigate(new Uri(...))
,但据我所知,这只能从 Silverlight 页面代码完成在后面。由于我使用的是 MVVM,因此命令的所有处理都在 ViewModel 类中进行。有没有办法在 ViewModel 中调用 Navigate
或以其他方式更改 Url?
为了澄清,xaml 包含以下 Button
:
<Button Content="1 Month View"
Command="{Binding OneMonthCommand}" />
ViewModel 类包含一个 OneMonthCommand
属性:
public ICommand OneMonthCommand { get; set; }
单击按钮时,我的 ICommand 实现的 Execute
方法被称为。问题是 - 如何在该方法中更改 Url?
I have a Silverlight 4 project which displays a chart and some buttons to allow the user to change the chart's date range. The date range can also be passed in via a query string parameter - something like http://myserver/MySilverlightPage/#?DateRange=OneMonth - and when the user clicks a button I'd like to update the Url as well.
I understand that the way to do this is to call this.NavigationService.Navigate(new Uri(...))
, but as far as I can tell this can only be done from the Silverlight page code behind. And since I'm using MVVM, all processing of the command takes place in the ViewModel class. Is there a way to call Navigate
or otherwise change the Url from within the ViewModel?
To clarify, the xaml includes the following Button
:
<Button Content="1 Month View"
Command="{Binding OneMonthCommand}" />
And the ViewModel class contains a OneMonthCommand
property:
public ICommand OneMonthCommand { get; set; }
When the button is clicked my ICommand implementation's Execute
method is called. The question is - how can I change the Url from within that method?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我发现这是我使用 MVVM 模式编写的 Silverlight 应用程序中的一个常见问题。我使用 NavigationHelper 类来集中导航逻辑。它看起来像这样:
然后,我让 ViewModel 有一个 NavigationHelper 属性,该属性是在构造 ViewModel 时由页面设置的。
顺便说一句,在 ViewModel 的构造函数中传递 NavigationHelper 似乎会更简单。但根据我的经验,ViewModel 的非默认构造函数使得在 Blend 的设计时工作变得更加困难。
I have found this to be a common problem in Silverlight applications I write using the MVVM pattern. I use a NavigationHelper class to centralize logic around navigation. It looks something like this:
Then, I have the ViewModel have a NavigationHelper property, which is set by the page when the ViewModel is constructed.
BTW, it seems like it would be simpler to have the NavigationHelper passed in the ViewModel's constructor. But having non-default constructors for the ViewModel makes it harder to get things working at design-time in Blend, in my experience.
如果您只是进行常规导航,则应该使用常规的超链接按钮。如果您尝试导航以响应其他事件,那么您可以使用消息传递。
另一种方法是让视图将 NavigationService 类传递给您的 ViewModel,如果您使用基本页面和基本视图模型,您将能够在不需要每个视图模型和视图了解移交的情况下发生这种情况正在发生。
If you're just doing regular navigation, you should use regular HyperlinkButtons. If you're trying to navigate in response to other events though, then you could use messaging.
An alternative is to have the View pass the NavigationService class in to your ViewModel, and if you use a base page and base viewmodel you will be able to have it happen in those without the requirement of each viewmodel and view knowing about the hand-off taking place.
使用 MVVM 并不排除使用超链接按钮(如果它们可以完成您需要的工作)。
正如您所发现的,NavigationService.Navigate 的问题在于它需要了解页面的上下文。
我不认为当您在代码隐藏中设置数据上下文时将当前视图注入回其视图模型被认为“太邪恶”。通常,如果 View 对 ViewModel 了解太多,情况会更糟。
Using MVVM does not exclude the use of Hyperlink buttons if they will do the job you require.
The problem, as you found, with NavigationService.Navigate is that it requires knowledge of the a page for its context.
I don't think it is considered "too evil" to inject your current view back into it's view model when you set the datacontext in codebehind. It is generally worse for the View to know too much about its ViewModel.