MVVM - Liên kết dữ liệu WPF
Trong chương này, chúng ta sẽ tìm hiểu cách liên kết dữ liệu hỗ trợ mẫu MVVM. Liên kết dữ liệu là tính năng chính giúp phân biệt MVVM với các mẫu phân tách giao diện người dùng khác như MVC và MVP.
Đối với liên kết dữ liệu, bạn cần có một dạng xem hoặc tập hợp các phần tử giao diện người dùng được xây dựng, sau đó bạn cần một số đối tượng khác mà các liên kết sẽ trỏ tới.
Các phần tử giao diện người dùng trong một dạng xem được liên kết với các thuộc tính được hiển thị bởi ViewModel.
Thứ tự mà View và ViewModel được xây dựng tùy thuộc vào tình huống, vì chúng tôi đã đề cập đến View trước.
Một View và ViewModel được xây dựng và DataContext của View được đặt thành ViewModel.
Liên kết có thể là liên kết dữ liệu OneWay hoặc TwoWay để chuyển dữ liệu qua lại giữa View và ViewModel.
Chúng ta hãy xem xét các ràng buộc dữ liệu trong cùng một ví dụ. Dưới đây là mã XAML của StudentView.
<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"
xmlns:vml = "clr-namespace:MVVMDemo.VML"
vml:ViewModelLocator.AutoHookedUpViewModel = "True"
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>
Nếu bạn nhìn vào mã XAML ở trên, bạn sẽ thấy rằng ItemsControl được liên kết với bộ sưu tập Sinh viên do ViewModel hiển thị.
Bạn cũng có thể thấy rằng thuộc tính của mô hình Sinh viên cũng có các ràng buộc riêng lẻ của chúng và những ràng buộc này được liên kết với Hộp văn bản và Khối văn bản.
ItemSource của ItemsControl có thể liên kết với thuộc tính Students, vì DataContext tổng thể cho Chế độ xem được đặt thành ViewModel.
Các ràng buộc riêng lẻ của các thuộc tính ở đây cũng là các liên kết DataContext, nhưng chúng không ràng buộc với chính ViewModel, do cách hoạt động của ItemSource.
Khi một nguồn mặt hàng liên kết với bộ sưu tập của nó, nó sẽ hiển thị một vùng chứa cho mỗi mặt hàng khi hiển thị và nó đặt DataContext của vùng chứa đó thành mặt hàng. Vì vậy, DataContext tổng thể cho mỗi hộp văn bản và khối văn bản trong một hàng sẽ là một Sinh viên riêng lẻ trong bộ sưu tập. Và bạn cũng có thể thấy rằng các ràng buộc này đối với TextBox là liên kết dữ liệu TwoWay và đối với TextBlock thì đó là liên kết dữ liệu OneWay vì bạn không thể chỉnh sửa TextBlock.
Khi bạn chạy lại ứng dụng này, bạn sẽ thấy kết quả sau.
Bây giờ chúng ta hãy thay đổi văn bản trong hộp văn bản thứ hai của hàng đầu tiên từ Allain thành Upston và nhấn tab để mất tiêu điểm. Bạn sẽ thấy rằng văn bản TextBlock cũng được cập nhật.
Điều này là do các ràng buộc của TextBox được đặt thành TwoWay và nó cũng cập nhật Mô hình, và từ mô hình, TextBlock lại được cập nhật.