使用 MVVM 設計模式時,實作切換頁面(Page)的方法
網上搜一搜有關『WPF 切換頁面』就會發現非常多各方大大提供教學(感謝在心中~),大都是使用 WinForm 方式實作
如何在 MVVM 模式下實作教學就真的不多了……這次就把我的作法整理如下,話不多說直接上 code 說明~
延續我前一篇 [WPF] MVVM 設計模式下全域屬性(Global Property)實作與 UI 數據雙向同步綁定的方法 的方法先在全域屬性的類別中加入以下程式碼
private const string InitMainActivePageName = "StartPageView";
private static string _MainActivePageName = InitMainActivePageName;
public static string MainActivePageName
{
get { return _MainActivePageName; }
set
{
if ((value == null) || (value == ""))
{
MainActivePage = new Uri(@"../View/" + InitMainActivePageName + ".xaml", UriKind.Relative);
_MainActivePageName = InitMainActivePageName;
}
else
{
try
{
MainActivePage = new Uri(@"../View/" + value + ".xaml", UriKind.Relative);
_MainActivePageName = value;
}
catch
{
MainActivePage = new Uri(@"../View/" + InitMainActivePageName + ".xaml", UriKind.Relative);
_MainActivePageName = InitMainActivePageName;
}
}
StaticPropertyChanged?.Invoke(null, new PropertyChangedEventArgs(nameof(MainActivePageName)));
}
}
private static Uri _MainActivePage = new Uri(@"../View/" + InitMainActivePageName + ".xaml", UriKind.Relative);
public static Uri MainActivePage
{
get { return _MainActivePage; }
set
{
_MainActivePage = value;
StaticPropertyChanged?.Invoke(null, new PropertyChangedEventArgs(nameof(MainActivePage)));
}
}
設計想法是改變 MainActivePageName 這個 string 屬性聯動改變 MainActivePage 這個 Uri 屬性
話句話說就是前端 UI 的 View 的 Frame 就綁定 MainActivePage,而 ViewModel 透過改變 MainActivePageName 就可以達到切換到對應的 Page 的 View
要注意的是 MainActivePageName 是各別 Page 的 XXXView.xaml,不用打上 .xaml,因為上面已經組好這部分的字串,這部分可以自行修改成自己習慣的方式
另外是我習慣把這個 GlobalData 放在專案根目錄 Root 下,View 放在另外創建的 View 目錄下,所以會開頭組一個 "../View/" 這個字串!
首先在主視窗加入一個 Frame 控制元件來做 Page 的容器,程式碼如下
<Window ...
xmlns:root="clr-namespace:MyProject"
...>
<Window.Resources>
<root:GlobalData x:Key="Global"/>
</Window.Resources>
<Grid>
<Frame Source="{Binding Source={StaticResource Global}, Path=MainActivePage}" NavigationUIVisibility="Hidden"/>
</Grid>
</Window>
到這裡開始另外創三個 Page 分別為 StartPageView / NextPageView / LastPageView,分別程式碼如下
StartPageView 的 View 部分加入一個按鈕
<Button Width="120" Height="28" FontSize="18" Margin="40, 60, 0, 0"
Content="Switch to NextPage" Click="NextPage_Click"></Button>
StartPageView 的 Code-Behind 部分
private void NextPage_Click(object sender, RoutedEventArgs e)
{
GlobalData.MainActivePageName0 = "NextPageView";
}
NextPageView 的 View 部分加入兩個按鈕
<Button Width="120" Height="36" FontSize="18" Margin="40, 60, 0, 0"
Content="Switch to LastPage" Click="LastPage_Click"></Button>
<Button Width="120" Height="36" FontSize="18" Margin="40, 60, 0, 0"
Content="Switch to StartPage" Click="StartPage_Click"></Button>
NextPageView 的 Code-Behind 部分
private void LastPage_Click(object sender, RoutedEventArgs e)
{
GlobalData.MainActivePageName = "LastPageView";
}
private void StartPage_Click(object sender, RoutedEventArgs e)
{
GlobalData.MainActivePageName = "StartPageView";
}
LastPageView 的 View 部分加入兩個按鈕
<Button Width="120" Height="36" FontSize="18" Margin="40, 60, 0, 0"
Content="Switch to StartPage" Click="StartPage_Click"></Button>
<Button Width="120" Height="36" FontSize="18" Margin="40, 60, 0, 0"
Content="Switch to NextPage" Click="NextPage_Click"></Button>
LastPageView 的 Code-Behind 部分
private void StartPage_Click(object sender, RoutedEventArgs e)
{
GlobalData.MainActivePageName = "StartPageView";
}
private void NextPage_Click(object sender, RoutedEventArgs e)
{
GlobalData.MainActivePageName = "NextPageView";
}
這部分只是示範如何使用,先用 WinForm 樣式呼叫事件處理,請自行改成 RelayCommand,請參考 [WPF] MVVM 軟體架構模式 - 透過 RelayCommand 綁定方法 (無參數型)
只要前置處理做好,後續就方便切換頁面,只要改變對應 Page 的檔案名就可以切換了!
另外提一下,建議全域屬性 Uri 可以加入一些錯誤處理避免開發過程中不小心打錯 Page 名或是綁定到空 Page 造成程式錯誤的問題!!
完結灑花~XD