新建WPF應用(.NET Framework)
2.新建目錄
使用MVVM框架,各目錄作用如下:
Styles:用于存放樣式資源文件。
Utilties:用于存放自定義控件,命令父類,ViewModel父類,DataTemplate.xaml,通用工具類。
Model:用于存放與業務邏輯或數據相關的類,M層。
View:用于存放用戶界面的,V層。
ViewModel:用于存放所有ViewModel類,連接Model、View,VM層。
3.Utilties添加文件
添加RelayCommand.cs,ViewModelBase.cs,DataTemplate.xaml。
3.1RelayCommand.cs
實現ICommand接口,存放命令實際執行的委托與判斷命令是否可執行的委托。
代碼:
using System;
using System.Windows.Input;namespace WpfApp1.Utilties
{
internal class RelayCommand:ICommand
{
private Action<object> _execute;
private Func<object, bool> _canExecute;
/// <summary>
/// 將CanExecuteChanged事件的訂閱/取消訂閱轉發給CommandManager.RequerySuggested事件。
/// CommandManager.RequerySuggested事件是WPF全局靜態事件,每當用戶進行鼠標按鍵/移動、鍵盤輸入等操作時,WPF會自動觸發該事件使所有綁定命令執行CanExecute方法。
/// 可通過命令對象的RaiseCanExecuteChanged方法主動觸發CanExecuteChanged事件,從而觸發 CommandManager.RequerySuggested事件。
/// </summary>
public event EventHandler CanExecuteChanged
{
add {CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public RelayCommand(Action<object> execute, Func<object, bool> canExecute)
{
_execute = execute;
_canExecute = canExecute;
}
/// <summary>
/// CanExecute方法返回值會影響到控件使能
/// </summary>
public bool CanExecute(object parameter)=>_canExecute==null||_canExecute(parameter);
public void Execute(object parameter)=>_execute(parameter);
}
}
3.2ViewModelBase.cs
實現INotifyPropertyChanged接口,用以在ViewModel層屬性變化時通知UI更新。
代碼:
using System.ComponentModel;
using System.Runtime.CompilerServices;namespace WpfApp1.Utilties
{
class ViewModelBase:INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// ViewModel層屬性值發生變化后調用該方法,觸發PropertyChanged事件通知界面重新讀取該屬性以更新
/// </summary>
/// <param name="propertyName">屬性名稱,此處使用了CallerMemberName特性,如果你不傳參數,那么編譯器會自動把調用這個方法的成員名(比如屬性名)作為參數傳進來。</param>
public void OnPropertyChanged([CallerMemberName]string propertyName=null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
3.3DataTemplate.xaml
為ViewModel 到 View 的映射提供支持,用于實現界面切換;需要先將此文件添加入App.xaml。
App.xaml代碼:
<Application x:Class="WpfApp1.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApp1"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Utilties/DataTemplate.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
假設ViewModel目錄下存在MainPageViewModel.cs,在View目錄下存在MainPage.xaml。
DataTemplate.xaml代碼:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:viewModel="clr-namespace:WpfApp1.ViewModel"
xmlns:view="clr-namespace:WpfApp1.View"> <DataTemplate DataType="{x:Type viewModel:MainPageViewModel}">
<view:MainPage/>
</DataTemplate>
</ResourceDictionary>