檢視模型

檢視模型是 MV VM 中VM 。這是一個充當中間人的類,將模型公開給使用者介面(檢視),並處理來自檢視的請求,例如按鈕點選引發的命令。這是一個基本的檢視模型:

public class CustomerEditViewModel
{
    /// <summary>
    /// The customer to edit.
    /// </summary>
    public Customer CustomerToEdit { get; set; }

    /// <summary>
    /// The "apply changes" command
    /// </summary>
    public ICommand ApplyChangesCommand { get; private set; }

    /// <summary>
    /// Constructor
    /// </summary>
    public CustomerEditViewModel()
    {
        CustomerToEdit = new Customer
                         {
                             Forename = "John",
                             Surname = "Smith"
                         };

        ApplyChangesCommand = new RelayCommand(
            o => ExecuteApplyChangesCommand(), 
            o => CustomerToEdit.IsValid);
    }

    /// <summary>
    /// Executes the "apply changes" command.
    /// </summary>
    private void ExecuteApplyChangesCommand()
    {
        // E.g. save your customer to database
    }
}

建構函式建立一個 Customer 模型物件並將其分配給 CustomerToEdit 屬性,以便它對檢視可見。

建構函式還建立一個 RelayCommand 物件並將其分配給 ApplyChangesCommand 屬性,再次使其對檢視可見。WPF 命令用於處理來自檢視的請求,例如按鈕或選單項單擊。

RelayCommand 有兩個引數 - 第一個是在執行命令時被呼叫的委託(例如,響應按鈕點選)。第二個引數是一個委託,它返回一個布林值,指示命令是否可以執行; 在這個例子中,它連線到客戶物件的 IsValid 屬性。如果返回 false,則會禁用繫結到此命令的按鈕或選單項(其他控制元件的行為可能不同)。這是一個簡單但有效的功能,無需編寫程式碼來啟用或禁用基於不同條件的控制元件。

如果你確實啟動並執行了此示例,請嘗試清空其中一個 TextBoxes(將 Customer 模型置於無效狀態)。當你遠離 TextBox 時,你會發現應用按鈕被禁用。

關於客戶創造的評論

檢視模型不實現 INotifyPropertyChanged(INPC)。這意味著如果要將一個不同的 Customer 物件分配給 CustomerToEdit 屬性,那麼檢視的控制元件將不會更改以反映新物件 - TextBoxes 仍將包含前一個客戶的名字和姓氏。

示例程式碼的工作原理是因為 Customer 是在檢視模型的建構函式中建立的,之後它被分配給檢視的 DataContext(此時繫結被連線起來)。在實際應用程式中,你可能正在使用建構函式以外的方法從資料庫中檢索客戶。為了支援這一點,VM 應該實現 INPC,並且應該更改 CustomerToEdit 屬性以使用你在示例 Model 程式碼中看到的擴充套件getter 和 setter 模式,從而在 setter 中引發 PropertyChanged 事件。

檢視模型的 ApplyChangesCommand 不需要實現 INPC,因為命令不太可能改變。你需要,如果你建立了比其他構造的命令的地方,例如某種 Initialize() 方法來實現這種模式。

一般規則是:如果屬性繫結到任何檢視控制元件並且屬性的值能夠在建構函式之外的任何位置更改,則實現 INPC。如果僅在建構函式中分配屬性值,則不需要實現 INPC(並且你將在過程中節省一些輸入)。