【问题标题】:Is there a way to call Navigate from within the ViewModel?有没有办法从 ViewModel 中调用 Navigate?
【发布时间】:2011-04-13 08:38:39
【问题描述】:

我有一个 Silverlight 4 项目,它显示一个图表和一些按钮,允许用户更改图表的日期范围。日期范围也可以通过查询字符串参数传递——比如http://myserver/MySilverlightPage/#?DateRange=OneMonth——当用户点击一个按钮时,我也想更新 URL。

我知道这样做的方法是调用this.NavigationService.Navigate(new Uri(...)),但据我所知,这只能从后面的 Silverlight 页面代码中完成。由于我使用的是 MVVM,因此命令的所有处理都在 ViewModel 类中进行。有没有办法调用 Navigate 或以其他方式从 ViewModel 中更改 Url?

为了澄清,xaml 包括以下Button

<Button Content="1 Month View"
        Command="{Binding OneMonthCommand}" />

ViewModel 类包含一个OneMonthCommand 属性:

public ICommand OneMonthCommand { get; set; }

当点击按钮时,我的 ICommand 实现的 Execute 方法被调用。问题是 - 如何从该方法中更改 URL?

【问题讨论】:

    标签: silverlight silverlight-4.0 mvvm navigation


    【解决方案1】:

    我发现这是我使用 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 中工作变得更加困难。

    【讨论】:

    • 在您的案例中谁构造了 ViewModel?视图的代码隐藏?还是创建视图和视图模型的第三类?
    • 一般来说,我通常会在页面的 XAML 中将 ViewModel 创建为资源。但是当这还不够强大时,我会转向第三方创建者。我认为这种模式在任何一种情况下都适用。
    【解决方案2】:

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

    另一种方法是让 View 将 NavigationService 类传递给您的 ViewModel,如果您使用基本页面和基本视图模型,则无需每个视图模型和视图都知道正在进行交接。

    【讨论】:

      【解决方案3】:

      使用 MVVM 并不排除使用超链接按钮,如果它们可以完成您需要的工作。

      如您所见,NavigationService.Navigate 的问题在于它需要了解页面的上下文。

      当您在代码隐藏中设置数据上下文时,我认为将当前视图重新注入其视图模型不会被认为“太邪恶”。 View 对其 ViewModel 了解太多通常会更糟。

      【讨论】:

        猜你喜欢
        • 2019-07-25
        • 1970-01-01
        • 2020-10-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-11-17
        • 2011-05-20
        • 1970-01-01
        相关资源
        最近更新 更多