<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      WPF Stylet可以如何實現(xiàn)導航功能?

      前言

      本文是學習Stylet中導航Demo的總結,希望對你有所幫助。

      Demo所在的位置:

      先看一下導航的效果:

      首頁

      通過上面導航到Page 2:

      通過Page1導航到Page2:

      Stylet是如何實現(xiàn)導航的?

      先來看一下頁面布局:

      一共有ShellView、HeaderView、Page1View與Page2View一共四個View。

      ShellView的xaml如下:

      <Window x:Class="Stylet.Samples.NavigationController.Pages.ShellView"
              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
              xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
              xmlns:local="clr-namespace:Stylet.Samples.NavigationController.Pages"
              mc:Ignorable="d"
              Title="Navigation Controller sample" Height="450" Width="800"
              xmlns:s="https://github.com/canton7/Stylet"
              d:DataContext="{d:DesignInstance local:ShellViewModel}">
          <DockPanel>
              <ContentControl DockPanel.Dock="Top" s:View.Model="{Binding HeaderViewModel}"/>
              <ContentControl s:View.Model="{Binding ActiveItem}"/>
          </DockPanel>
      </Window>
      

      頁面的上部分通過s:View.Model="{Binding HeaderViewModel}"綁定到了HearView。

      下部分通過s:View.Model="{Binding ActiveItem}"綁定到了激活項的View。

      這里你可能會感到疑惑,ActiveItem這個屬性是哪里來的呢?

      ActiveItem這個屬性是在ConductorBaseWithActiveItem<T>中定義的:

      ShellViewModel繼承 Conductor<IScreen> Conductor<IScreen>繼承 ConductorBaseWithActiveItem<T>

      這里你就把ActiveItem理解成導航激活的那個ViewModel就行了,這個例子中要么是Page1ViewModel要么就是Page2ViewModel。

      現(xiàn)在來看一下NavigationController:

      public class NavigationController : INavigationController
      {
          private readonly Func<Page1ViewModel> page1ViewModelFactory;
          private readonly Func<Page2ViewModel> page2ViewModelFactory;
      
          public INavigationControllerDelegate Delegate { get; set; }
      
          public NavigationController(Func<Page1ViewModel> page1ViewModelFactory, Func<Page2ViewModel> page2ViewModelFactory)
          {
              this.page1ViewModelFactory = page1ViewModelFactory ?? throw new ArgumentNullException(nameof(page1ViewModelFactory));
              this.page2ViewModelFactory = page2ViewModelFactory ?? throw new ArgumentNullException(nameof(page2ViewModelFactory));
          }
      
          public void NavigateToPage1()
          {
              this.Delegate?.NavigateTo(this.page1ViewModelFactory());
          }
      
          public void NavigateToPage2(string initiator)
          {
              Page2ViewModel vm = this.page2ViewModelFactory();
              vm.Initiator = initiator;
              this.Delegate?.NavigateTo(vm);
          }
      }
      

      看一下INavigationController:

      public interface INavigationController
      {
          void NavigateToPage1();
          void NavigateToPage2(string initiator);
      }
      

      首先解決一個疑問,這里為什么使用private readonly Func<Page1ViewModel> page1ViewModelFactory;而不是直接使用Page1ViewModel呢?

      我們知道在C#中Func<Page1ViewModel>表示一個沒有參數(shù),返回值為Page1ViewModel的委托。

      再看看Bootstrapper中的ConfigureIoC方法:

      這樣寫的目的就是不是一開始就將Page1ViewModel與Page2ViewModel注入進來,而是在使用的時候才注入進來。

      我們發(fā)現(xiàn)在NavigationController中具體實現(xiàn)導航是通過INavigationControllerDelegate接口實現(xiàn)的,讓我們再來看看這個接口:

      public interface INavigationControllerDelegate
      {
          void NavigateTo(IScreen screen);
      }
      

      回到ShellViewModel,我們發(fā)現(xiàn)它實現(xiàn)了這個接口。

      來看下它的實現(xiàn):

       public void NavigateTo(IScreen screen)
       {
           this.ActivateItem(screen);
       }
      

      使用的是 Conductor<T>中的ActivateItem方法:

      當我們從頁面1導航到頁面2時:

      由于要導航去的Page2ViewModel不是當前的激活項Page1ViewModel,就會來到ChangeActiveItem方法:

      關閉之前的激活項,設置新的激活項。

      就成功導航到Page2ViewModel了,然后根據(jù)Page2ViewModel就會找到Page2View了,這樣就成功實現(xiàn)導航功能了。

      最后再來看一下有一個循環(huán)依賴問題:

      這里存在一個循環(huán)依賴關系:ShellViewModel -> HeaderViewModel -> NavigationController -> ShellViewModel。

      如果直接在NavigationController的構造函數(shù)中注入ShellViewModel就會引發(fā)這個循環(huán)依賴問題。

      作者通過在構建 NavigationController 后,再將 ShellViewModel 賦值給它的方式來打破這一循環(huán)依賴。

      最后

      Stylet導航功能的實現(xiàn)主要是通過Conductor<T>實現(xiàn)的。

      從作者的這個示例中學習了如何使用Stylet實現(xiàn)一個導航應用,還是學習到了很多知識的,感謝作者的付出!!

      posted @ 2025-08-15 10:57  mingupupup  閱讀(401)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 亚洲性日韩精品一区二区| 亚洲一区二区中文av| 国偷自产一区二区免费视频| 乱人伦人妻中文字幕不卡| 五月天激情国产综合婷婷婷| 人妻激情偷一区二区三区| 国产精品中文一区二区| 亚洲最大天堂在线看视频| 大陆精大陆国产国语精品| 性一交一乱一伦一| 亚洲国产精品无码久久电影| 久久精品人人槡人妻人人玩AV | 日韩熟女熟妇久久精品综合| 国产一区二区日韩在线| 国产人妻人伦精品婷婷| 毛茸茸性xxxx毛茸茸毛茸茸| 综合人妻久久一区二区精品| 国产在线观看播放av| 久久96热在精品国产高清| 丰满的少妇一区二区三区| 天堂av在线一区二区| 国产精品白丝久久av网站| 神农架林区| 亚洲二区中文字幕在线| 强奷白丝美女在线观看| 中文字幕无码中文字幕有码a| 激情四射激情五月综合网| 精品免费国产一区二区三区四区介绍| 亚洲av噜噜一区二区| 国产卡一卡二卡三免费入口| 欧美福利电影A在线播放| 国产一区二区三区禁18| 国产情侣激情在线对白| 中文字幕av中文字无码亚| 乌拉特中旗| 免费又大粗又爽又黄少妇毛片| a级亚洲片精品久久久久久久| 国产女人喷潮视频免费 | 午夜性刺激在线观看| 91精品亚洲一区二区三区| 亚洲欧美综合人成在线|