- MVVM 教程
- MVVM - 首頁
- MVVM – 簡介
- MVVM - 優勢
- MVVM - 職責
- MVVM - 第一個應用程式
- MVVM – 檢視繫結
- MVVM – 繫結ViewModel
- MVVM – WPF 資料繫結
- MVVM – WPF 資料模板
- MVVM – ViewModel 通訊
- MVVM – 層次結構與導航
- MVVM – 驗證
- MVVM – 依賴注入
- MVVM – 事件
- MVVM – 單元測試
- MVVM – 框架
- MVVM – 面試問題
- MVVM 有用資源
- MVVM - 快速指南
- MVVM - 有用資源
- MVVM - 討論
MVVM – 檢視繫結
本章將介紹將檢視與 ViewModel 繫結起來的不同方法。首先,讓我們看一下檢視優先構建,我們可以在 XAML 中宣告它。正如我們在上一章中看到的例子,我們已經從主視窗綁定了一個檢視。現在我們將看到其他繫結檢視的方法。
本章也將使用相同的示例。以下是相同的模型類實現。
using System.ComponentModel;
namespace MVVMDemo.Model {
public class StudentModel {}
public class Student : INotifyPropertyChanged {
private string firstName;
private string lastName;
public string FirstName {
get { return firstName; }
set {
if (firstName != value) {
firstName = value;
RaisePropertyChanged("FirstName");
RaisePropertyChanged("FullName");
}
}
}
public string LastName {
get { return lastName; }
set {
if (lastName != value) {
lastName = value;
RaisePropertyChanged("LastName");
RaisePropertyChanged("FullName");
}
}
}
public string FullName {
get {
return firstName + " " + lastName;
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string property) {
if (PropertyChanged != null) {
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
}
}
這是 ViewModel 類實現。這次 LoadStudents 方法在預設建構函式中被呼叫。
using MVVMDemo.Model;
using System.Collections.ObjectModel;
namespace MVVMDemo.ViewModel{
public class StudentViewModel {
public StudentViewModel() {
LoadStudents();
}
public ObservableCollection<Student> Students {
get;
set;
}
public void LoadStudents() {
ObservableCollection<Student> students = new ObservableCollection<Student>();
students.Add(new Student { FirstName = "Mark", LastName = "Allain" });
students.Add(new Student { FirstName = "Allen", LastName = "Brown" });
students.Add(new Student { FirstName = "Linda", LastName = "Hamerski" });
Students = students;
}
}
}
無論檢視是視窗、使用者控制元件還是頁面,解析器通常自上而下、從左到右工作。它在遇到每個元素時呼叫其預設建構函式。構建檢視有兩種方法。您可以使用任何一種。
- 在 XAML 中進行檢視優先構建
- 在程式碼隱藏中進行檢視優先構建
在 XAML 中進行檢視優先構建
一種方法是簡單地將您的 ViewModel 作為 DataContext 屬性設定程式中的巢狀元素新增,如下面的程式碼所示。
<UserControl.DataContext> <viewModel:StudentViewModel/> </UserControl.DataContext>
這是完整的檢視 XAML 檔案。
<UserControl x:Class="MVVMDemo.Views.StudentView"
xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d = "http://schemas.microsoft.com/expression/blend/2008"
xmlns:local = "clr-namespace:MVVMDemo.Views"
xmlns:viewModel = "clr-namespace:MVVMDemo.ViewModel"
mc:Ignorable = "d"
d:DesignHeight = "300" d:DesignWidth = "300">
<UserControl.DataContext>
<viewModel:StudentViewModel/>
</UserControl.DataContext>
<Grid>
<StackPanel HorizontalAlignment = "Left">
<ItemsControl ItemsSource = "{Binding Path = Students}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation = "Horizontal">
<TextBox Text = "{Binding Path = FirstName, Mode = TwoWay}"
Width = "100" Margin = "3 5 3 5"/>
<TextBox Text = "{Binding Path = LastName, Mode = TwoWay}"
Width = "100" Margin = "0 5 3 5"/>
<TextBlock Text = "{Binding Path = FullName, Mode = OneWay}"
Margin = "0 5 3 5"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</Grid>
</UserControl>
在程式碼隱藏中進行檢視優先構建
另一種方法是,您可以透過在檢視的程式碼隱藏中設定 DataContext 屬性來實現檢視優先構建。
通常,DataContext 屬性在檢視的建構函式方法中設定,但您也可以將其構造推遲到檢視的 Load 事件觸發。
using System.Windows.Controls;
namespace MVVMDemo.Views {
/// <summary>
/// Interaction logic for StudentView.xaml
/// </summary>
public partial class StudentView : UserControl {
public StudentView() {
InitializeComponent();
this.DataContext = new MVVMDemo.ViewModel.StudentViewModel();
}
}
}
在程式碼隱藏中而不是在 XAML 中構建檢視模型的一個原因是,檢視模型建構函式需要引數,但 XAML 解析只能在預設建構函式中定義時構建元素。
現在在這種情況下,檢視的 XAML 檔案將如下面的程式碼所示。
<UserControl x:Class = "MVVMDemo.Views.StudentView"
xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d = "http://schemas.microsoft.com/expression/blend/2008"
xmlns:local = "clr-namespace:MVVMDemo.Views"
mc:Ignorable = "d"
d:DesignHeight = "300"
d:DesignWidth = "300">
<Grid>
<StackPanel HorizontalAlignment = "Left">
<ItemsControl ItemsSource = "{Binding Path = Students}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation = "Horizontal"<
<TextBox Text = "{Binding Path = FirstName, Mode = TwoWay}"
Width = "100" Margin = "3 5 3 5"/>
<TextBox Text = "{Binding Path = LastName, Mode = TwoWay}"
Width = "100" Margin = "0 5 3 5"/>
<TextBlock Text = "{Binding Path = FullName, Mode = OneWay}"
Margin = "0 5 3 5"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</Grid>
</UserControl>
您可以在 MainWindow 中宣告此檢視,如 MainWindow.XAML 檔案所示。
<Window x:Class = "MVVMDemo.MainWindow"
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:MVVMDemo"
xmlns:views = "clr-namespace:MVVMDemo.Views"
mc:Ignorable = "d"
Title = "MainWindow" Height = "350" Width = "525">
<Grid>
<views:StudentView x:Name = "StudentViewControl"/>
</Grid>
</Window>
編譯並執行上述程式碼後,您將在主視窗上看到以下輸出。
我們建議您逐步執行以上示例,以便更好地理解。
廣告