有没有办法从 ViewModel 中调用 Navigate?

发布于 2024-09-19 23:32:23 字数 827 浏览 4 评论 0原文

我有一个 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

爱情眠于流年 2024-09-26 23:32:23

我发现这是我使用 MVVM 模式编写的 Silverlight 应用程序中的一个常见问题。我使用 NavigationHelper 类来集中导航逻辑。它看起来像这样:

public interface INavigationHelper
{
    void Home();
    void SomeOtherPage();
}

public class NavigationHelper : INavigationHelper
{
    private NavigationService _navSvc;

    public NavigationHelper(NavigationService navSvc)
    {
        _navSvc = navSvc;
    }

    public void Home()
    {
        _navSvc.Navigate(new Uri("/Home", UriKind.Relative));
    }

    public void SomeOtherPage()
    {
        _navSvc.Navigate(new Uri("/SomeOtherPage", UriKind.Relative));
    }
}

然后,我让 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:

public interface INavigationHelper
{
    void Home();
    void SomeOtherPage();
}

public class NavigationHelper : INavigationHelper
{
    private NavigationService _navSvc;

    public NavigationHelper(NavigationService navSvc)
    {
        _navSvc = navSvc;
    }

    public void Home()
    {
        _navSvc.Navigate(new Uri("/Home", UriKind.Relative));
    }

    public void SomeOtherPage()
    {
        _navSvc.Navigate(new Uri("/SomeOtherPage", UriKind.Relative));
    }
}

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.

渡你暖光 2024-09-26 23:32:23

如果您只是进行常规导航,则应该使用常规的超链接按钮。如果您尝试导航以响应其他事件,那么您可以使用消息传递。

另一种方法是让视图将 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.

许一世地老天荒 2024-09-26 23:32:23

使用 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文