MVVM Light 5.0:如何使用导航服务 [英] MVVM Light 5.0: How to use the Navigation service

查看:39
本文介绍了MVVM Light 5.0:如何使用导航服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

MVVM Light 的最新版本说明,已经表明 MVVM Light 现在提供了导航服务".

In the latest release of MVVM Light note, it has been indicated that MVVM Light now provides a "Navigation Service".

但我和我的朋友谷歌找不到如何使用它.

But myself and my friend google are unable to find how to use it.

我可以看到我可以向 ServiceLocator 请求一个 INavigationService,所以我知道如何请求转到另一个页面,但是:

I can see that I can ask a INavigationService to the ServiceLocator, so I see how I can ask to go to another page, but:

  1. 我创建了一个新窗口,我希望在其中为页面"保留一个特定区域,我该如何指定?
  2. 如何指定所有可用的页面?有什么需要我打电话的吗?
  3. INavigationService的参数的格式是什么
  1. I created a new windows, where I expect to reserve a specific zone for the "page", how do I specify this?
  2. How do I specify all the available pages? Is there something I should call?
  3. What would be the format of the parameters given to the INavigationService

有没有关于这个库的官方文档?因为目前我发现它编码得很好并且工作正常,但是当我必须搜索如何使用它时,我从来没有找到展示如何使用它的文档/示例,除了他的博客有一些条目.这是非常令人沮丧的.我找到的唯一文档是this,我不太熟悉Pluralsight,但似乎必须按月订阅(作为个人,试图在我的空闲时间申请,这是不可能的).

Is there any official documentation for this library? Because currently I find it nicely coded and working fine, but when I've to search how to use it, I never find a documentation/sample showing how to, except his blog which has some entry. This is very frustrating. The only documentation I found is this, I'm not very familiar with Pluralsight, but it seems that it's mandatory to take a monthly subscription(which as an individual, which is trying to make an application on my free time, isn't possible).

推荐答案

是的,MvvmLight 在其最新版本中引入了 NavigationService 但他们没有提供任何关于 Wpf 的实现(您可以在 WP、Metroapps 中使用已实现的 NavigationService ..)但不幸的是不是 Wpf,您需要自己实现,这是我目前的做法(credit)

Yes, MvvmLight introduced the NavigationService in their last version but they did't offer any implementation regarding Wpf (you can use the Implemented NavigationService in WP, Metroapps, ..) but unfortunately not Wpf, you need to implement that by your self, here how i am currently doing it (credit)

首先创建实现MvvmLight INavigationService

public interface IFrameNavigationService : INavigationService
{
    object Parameter { get; }  
}

Parameter 用于在ViewModels 之间传递对象,INavigationServiceGalaSoft.MvvmLight.Views 的一部分代码> 命名空间

the Parameter is used to pass objects between ViewModels, and the INavigationService is part of GalaSoft.MvvmLight.Views namespace

然后像这样实现那个接口

then implemente that interface like so

    class FrameNavigationService : IFrameNavigationService,INotifyPropertyChanged
    {
        #region Fields
        private readonly Dictionary<string, Uri> _pagesByKey;
        private readonly List<string> _historic;
        private string _currentPageKey;  
        #endregion
        #region Properties                                              
        public string CurrentPageKey
        {
            get
            {
                return _currentPageKey;
            }

            private  set
            {
                if (_currentPageKey == value)
                {
                    return;
                }

                _currentPageKey = value;
                OnPropertyChanged("CurrentPageKey");
            }
        }
        public object Parameter { get; private set; }
        #endregion
        #region Ctors and Methods
        public FrameNavigationService()
        {
            _pagesByKey = new Dictionary<string, Uri>();
            _historic = new List<string>();
        }                
        public void GoBack()
        {
            if (_historic.Count > 1)
            {
                _historic.RemoveAt(_historic.Count - 1);
                NavigateTo(_historic.Last(), null);
            }
        }
        public void NavigateTo(string pageKey)
        {
            NavigateTo(pageKey, null);
        }

        public virtual void NavigateTo(string pageKey, object parameter)
        {
            lock (_pagesByKey)
            {
                if (!_pagesByKey.ContainsKey(pageKey))
                {
                    throw new ArgumentException(string.Format("No such page: {0} ", pageKey), "pageKey");
                }

                var frame = GetDescendantFromName(Application.Current.MainWindow, "MainFrame") as Frame;

                if (frame != null)
                {
                    frame.Source = _pagesByKey[pageKey];
                }
                Parameter = parameter;
                _historic.Add(pageKey);
                CurrentPageKey = pageKey;
            }
        }

        public void Configure(string key, Uri pageType)
        {
            lock (_pagesByKey)
            {
                if (_pagesByKey.ContainsKey(key))
                {
                    _pagesByKey[key] = pageType;
                }
                else
                {
                    _pagesByKey.Add(key, pageType);
                }
            }
        }

        private static FrameworkElement GetDescendantFromName(DependencyObject parent, string name)
        {
            var count = VisualTreeHelper.GetChildrenCount(parent);

            if (count < 1)
            {
                return null;
            }

            for (var i = 0; i < count; i++)
            {
                var frameworkElement = VisualTreeHelper.GetChild(parent, i) as FrameworkElement;
                if (frameworkElement != null)
                {
                    if (frameworkElement.Name == name)
                    {
                        return frameworkElement;
                    }

                    frameworkElement = GetDescendantFromName(frameworkElement, name);
                    if (frameworkElement != null)
                    {
                        return frameworkElement;
                    }
                }
            }
            return null;
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }
        #endregion
    }

上面代码中的 MainFrame 是一个简单的 Frame 控件的 x:Name 定义在 Xaml 中,用于在页面之间导航(自定义根据您的需要)

the MainFrame in the above code is the x:Name of a simple Frame control Defined in Xaml used to navigate between pages (customize based on your needs)

第二:在viewmodellocator中,初始化您的导航服务(SetupNavigation()),以便您可以在您的视图模型中使用它:

Second: In the viewmodellocator, init your navigation service (SetupNavigation()), so you can use it in your viewmodels:

static ViewModelLocator()
{
     ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);

     SetupNavigation();

     SimpleIoc.Default.Register<MainViewModel>();
     SimpleIoc.Default.Register<LoginViewModel>();
     SimpleIoc.Default.Register<NoteViewModel>();            
 }
 private static void SetupNavigation()
 {
     var navigationService = new FrameNavigationService();
     navigationService.Configure("LoginView", new Uri("../Views/LoginView.xaml",UriKind.Relative));
     navigationService.Configure("Notes", new Uri("../Views/NotesView.xaml", UriKind.Relative));            

      SimpleIoc.Default.Register<IFrameNavigationService>(() => navigationService);
 }

第三:最后,使用服务,例如

 public LoginViewModel(IFrameNavigationService navigationService)
 {
      _navigationService = navigationService; 
 }
...
_navigationService.NavigateTo("Notes",data);
..

编辑

可以在此存储库中找到明确的示例.

An explicit sample can be found at this repo.

这篇关于MVVM Light 5.0:如何使用导航服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆