【问题标题】:MVVM Silverlight and page navigationMVVM Silverlight 和页面导航
【发布时间】:2011-08-26 13:53:41
【问题描述】:

我刚开始使用 Silverlight 以及 MVVM 模型。 在执行页面导航并将参数从一个页面发送到另一个页面时,.. 使用查询字符串是最被接受的方法吗?

在执行页面导航时如何传递参数似乎是一个很大的困惑。至少我在各种网络资源上找到了几个关于此的主题,但似乎没有人同意“最佳实践”方法。

【问题讨论】:

    标签: silverlight mvvm navigation


    【解决方案1】:

    注意:以下在 NavigationContext 中使用查询字符串的解决方案适用于浏览器内外。

    您通常将 UriMapper 设置为:

               <navigation:Frame Source="/Home" >
                    <navigation:Frame.UriMapper>
                        <uriMapper:UriMapper>
                            <uriMapper:UriMapping Uri="" 
                                       MappedUri="/Views/Home.xaml"/>
                            <uriMapper:UriMapping Uri="/{pageName}/{key}" 
                                       MappedUri="/Views/{pageName}.xaml?entityGuid={key}"/>
                            <uriMapper:UriMapping Uri="/{pageName}" 
                                       MappedUri="/Views/{pageName}.xaml"/>
                        </uriMapper:UriMapper>
                    </navigation:Frame.UriMapper>
                </navigation:Frame>
    

    然后为了让 NavigationContext 进入视图模型,你可以像这样向你的视图添加一个帮助器:

    <navigation:Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                     xmlns:helpers="clr-namespace:MyApp.Helpers"
                     xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
                     DataContext="{Binding Path=Entity, Source={StaticResource Locator}}"
                     helpers:Navigator.Source="{Binding}">
    

    然后你有一个像这样的附加属性助手(我从其他人那里修改了这个,虽然我忘记了谁):

    using System.Windows;
    using System.Windows.Controls;
    
    namespace MyApp.Helpers
    {
    
        public interface INavigable
        {
            System.Windows.Navigation.NavigationService NavigationService { get; set; }
            System.Windows.Navigation.NavigationContext NavigationContext { get; set; }
        }
    
    
        public static class Navigator
        {
            public static INavigable GetSource(DependencyObject obj)
            {
                return (INavigable)obj.GetValue(SourceProperty);
            }
    
            public static void SetSource(DependencyObject obj, INavigable value)
            {
                obj.SetValue(SourceProperty, value);
            }
    
            public static readonly DependencyProperty SourceProperty =
                 DependencyProperty.RegisterAttached("Source", typeof(INavigable), typeof(Navigator), new PropertyMetadata(OnSourceChanged));
    
            private static void OnSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {
                Page page = (Page)d;
    
                page.Loaded += PageLoaded;
            }
    
            private static void PageLoaded(object sender, RoutedEventArgs e)
            {
                Page page = (Page)sender;
    
                INavigable navSource = GetSource(page);
    
                if (navSource != null)
                {
                    navSource.NavigationService = page.NavigationService;
                    navSource.NavigationContext = page.NavigationContext;
                }
            }
        }
    }
    

    然后将以下内容添加到您的 ViewModel:

        private NavigationContext _NavigationContext;
        public NavigationContext NavigationContext {
            get { return _NavigationContext; }
            set {
                if (_NavigationContext == value)
                    return;
                _NavigationContext = value;
                RaisePropertyChanged("NavigationContext");
            }
        }
        protected override void RaisePropertyChanged(string propertyName) {
            base.RaisePropertyChanged(propertyName);
    
            switch (propertyName) {
                case "NavigationContext":
                    if (NavigationContext.QueryString.ContainsKey("entityGuid")) {
                        if (NavigationContext.QueryString["entityGuid"].Equals("new", StringComparison.InvariantCultureIgnoreCase)) {
                            LoadNewEntity();  // your 'new' logic
                        } else {
                            this.EntityGuid = new Guid(NavigationContext.QueryString["entityGuid"]);
                            LoadExistingEntity(EntityGuid);  // your 'existing' logic
                        }
                    }
                    break;
            }
        }
    

    【讨论】:

    • 我没有从 xaml 中得到这个字符串:DataContext="{Binding Path=Entity, Source={StaticResource Locator}}" 在我的项目中找不到定位器
    • 抱歉,这是很多人做的 MVVM 轻量级的事情。看看这篇文章,它确实比在资源中设置 ViewModel 好得多:
    • 谢谢 :) 这应该让我重回正轨!
    • 作为参考,我想我找到了你的原始出处:garfoot.com/blog/2010/09/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-30
    相关资源
    最近更新 更多