日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

MVVMLight 实现指定Frame控件的导航

發布時間:2025/3/15 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MVVMLight 实现指定Frame控件的导航 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
MVVMLight 實現指定Frame控件的導航 原文:MVVMLight 實現指定Frame控件的導航

在UWP開發中,利用漢堡菜單實現導航是常見的方法。漢堡菜單導航一般都需要新建一個Frame控件,并對其進行導航,但是在MvvmLight框架默認的NavigationService中,只能對根Frame進行導航,這就需要我們實現自己的NavigationService了。

MvvmLight源碼簡析

  • GalaSoft.MvvmLight.Views命名空間下的NavigationService繼承了同命名空間下的INavigationService接口但是并沒有實現。
namespace GalaSoft.MvvmLight.Views {public class NavigationService : INavigationService{public const string RootPageKey = "-- ROOT --";public const string UnknownPageKey = "-- UNKNOWN --";public NavigationService();public string CurrentPageKey { get; }public void Configure(string key, Type pageType);public void GoBack();public void NavigateTo(string pageKey);public virtual void NavigateTo(string pageKey, object parameter);} }
  • 具體的功能實現是在GalaSoft.MvvmLight.Platform命名空間下的NavigationService中,根據平臺的不同有不同的實現。
  • 我們要做的就是自己實現INavigationService并自己定義導航的Frame控件

實現自己的NavigationService

很奇怪,官方公布源碼的那個網站上沒有找到Win10平臺的Platform源碼,所以我就把Win8.1的NavigationService實現復制下來,經測試能正常用。

  • 在public virtual void NavigateTo(string pageKey, object parameter)方法下,我們可以看到這樣一行代碼:
    var frame = ((Frame)Window.Current.Content);

    這個語句就定義了用來導航的Frame控件(不止這個方法中有,另外2個方法中也有類似的語句)。

  • 我們把這幾個地方的frame變量值設置成自己的Frame控件就可以了。
  • 我的修改方法:

    • 我的Frame控件是放在MainPage中的,主要是為了實現漢堡菜單導航,我想大部分有這種需求的人都是為了實現類似的導航吧。

    • 首先在MainPage.xaml.cs里面加入一個MainPage類型的靜態Public變量
    • 然后再構造函數中給變量賦值為this
    • 還要給自己的Frame控件寫一個屬性來獲取它

      public static MainPage MPage; // 1.public Frame MyFrame // 3. {get{return ContentFrame; //ContentFrame是xaml中定義的Frame控件的名字} }public MainPage() {InitializeComponent();SystemNavigationManager.GetForCurrentView().BackRequested += SystemNavigationManagerBackRequested;Loaded += (s, e) =>{Vm.RunClock();};MPage = this; // 2. }
    • 然后就可以在自己的NavigationService里面使用自己的Frame了。

      //var frame = ((Frame)Window.Current.Content); // 之前的語句 var frame = MainPage.MPage.MyFrame; // 自己寫的新語句

      這樣我們就把NavigationService的導航Frame設置成了MainPage里面的ContentFrame控件。

  • 不過我這個方法還不是最優的,因為這樣寫就把MainPage和NavigationService直接聯系起來了,增加了耦合性。我看到WPF中可以通過下面這個方法來獲取指定名字的Frame控件,不過在UWP里面沒有這個方法。
    var frame = GetDescendantFromName(Application.Current.MainWindow, "MainFrame") as Frame;

如果誰有更好的辦法的話麻煩在評論里面告訴我,萬分感謝。

效果圖

MyNavigationService代碼

using GalaSoft.MvvmLight.Views;using Mvvm_HutHelper.View;using System;using System.Collections.Generic;using System.Linq;namespace Mvvm_HutHelper.Model{class MyNavigationService : INavigationService{/// <summary>/// The key that is returned by the <see cref="CurrentPageKey"/> property/// when the current Page is the root page./// </summary>public const string RootPageKey = "-- ROOT --";/// <summary>/// The key that is returned by the <see cref="CurrentPageKey"/> property/// when the current Page is not found./// This can be the case when the navigation wasn't managed by this NavigationService,/// for example when it is directly triggered in the code behind, and the/// NavigationService was not configured for this page type./// </summary>public const string UnknownPageKey = "-- UNKNOWN --";private readonly Dictionary<string, Type> _pagesByKey = new Dictionary<string, Type>();/// <summary>/// The key corresponding to the currently displayed page./// </summary>public string CurrentPageKey{get{lock (_pagesByKey){//var frame = ((Frame)Window.Current.Content);var frame = MainPage.MPage.MyFrame;if (frame.BackStackDepth == 0){return RootPageKey;}if (frame.Content == null){return UnknownPageKey;}var currentType = frame.Content.GetType();if (_pagesByKey.All(p => p.Value != currentType)){return UnknownPageKey;}var item = _pagesByKey.FirstOrDefault(i => i.Value == currentType);return item.Key;}}}/// <summary>/// If possible, discards the current page and displays the previous page/// on the navigation stack./// </summary>public void GoBack(){//var frame = ((Frame)Window.Current.Content);var frame = MainPage.MPage.MyFrame;if (frame.CanGoBack){frame.GoBack();}}/// <summary>/// Displays a new page corresponding to the given key. /// Make sure to call the <see cref="Configure"/>/// method first./// </summary>/// <param name="pageKey">The key corresponding to the page/// that should be displayed.</param>/// <exception cref="ArgumentException">When this method is called for /// a key that has not been configured earlier.</exception>public void NavigateTo(string pageKey){NavigateTo(pageKey, null);}/// <summary>/// Displays a new page corresponding to the given key,/// and passes a parameter to the new page./// Make sure to call the <see cref="Configure"/>/// method first./// </summary>/// <param name="pageKey">The key corresponding to the page/// that should be displayed.</param>/// <param name="parameter">The parameter that should be passed/// to the new page.</param>/// <exception cref="ArgumentException">When this method is called for /// a key that has not been configured earlier.</exception>public virtual void NavigateTo(string pageKey, object parameter){lock (_pagesByKey){if (!_pagesByKey.ContainsKey(pageKey)){throw new ArgumentException(string.Format("No such page: {0}. Did you forget to call NavigationService.Configure?",pageKey),"pageKey");}//var frame = ((Frame)Window.Current.Content); // 這句設置導航時用到的Frame控件為根Framevar frame = MainPage.MPage.MyFrame;frame.Navigate(_pagesByKey[pageKey], parameter);}}/// <summary>/// Adds a key/page pair to the navigation service./// </summary>/// <param name="key">The key that will be used later/// in the <see cref="NavigateTo(string)"/> or <see cref="NavigateTo(string, object)"/> methods.</param>/// <param name="pageType">The type of the page corresponding to the key.</param>public void Configure(string key, Type pageType){lock (_pagesByKey){if (_pagesByKey.ContainsKey(key)){throw new ArgumentException("This key is already used: " + key);}if (_pagesByKey.Any(p => p.Value == pageType)){throw new ArgumentException("This type is already configured with key " + _pagesByKey.First(p => p.Value == pageType).Key);}_pagesByKey.Add(key,pageType);}}}}

參考資料

MVVM Light 5.0: How to use the Navigation service

MvvmLight SourceCode

posted on 2018-06-06 14:33 NET未來之路 閱讀(...) 評論(...) 編輯 收藏

轉載于:https://www.cnblogs.com/lonelyxmas/p/9144982.html

總結

以上是生活随笔為你收集整理的MVVMLight 实现指定Frame控件的导航的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。