Silverlight - Xem mô hình
Trong chương này, chúng ta sẽ xem xét một kỹ thuật quan trọng trong phát triển phần mềm của Silverlight, việc sử dụng View Models.
Các view model là một phần quan trọng, giới thiệu một kỹ thuật được gọi là trình bày tách biệt bằng cách giữ cho khung nhìn tách biệt khỏi mô hình.
View Models cung cấp một cách để đạt được bản trình bày riêng biệt và chúng tôi sẽ xem cách họ khai thác liên kết dữ liệu của Silverlight để giảm lượng mã cần thiết trong giao diện người dùng của bạn.
Những thách thức về phát triển giao diện người dùng
View Modelsđược thiết kế để giải quyết một số vấn đề thường xảy ra khi phát triển phần mềm giao diện người dùng. Có lẽ điều quan trọng nhất là mã giao diện người dùng thường khó kiểm tra chặt chẽ, đặc biệt là với các bài kiểm tra đơn vị tự động. Ngoài ra còn có các vấn đề về chất lượng mã có thể ảnh hưởng đến tính linh hoạt và khả năng bảo trì liên tục của mã của bạn.
Nếu bạn đi theo con đường ít phản kháng nhất mà các công cụ thiết kế của Visual Studio dẫn bạn xuống, bạn có thể kết thúc bằng việc đặt quá nhiều mã vào mã phía sau.
Rất phổ biến khi thấy một lượng lớn chức năng ứng dụng được thêm vào mã phía sau.
Rất ít nhà phát triển thực sự có kế hoạch đưa logic nghiệp vụ vào một lớp giao diện người dùng, nhưng vì đó là nơi Visual Studio đặt các trình xử lý sự kiện của bạn nên nó trở thành một nơi quá thuận tiện để hoàn thành công việc.
Người ta chấp nhận rộng rãi rằng phần mềm dễ phát triển và bảo trì hơn nếu các lớp có trách nhiệm được xác định rõ ràng và thu hẹp hợp lý.
Công việc của mã phía sau là tương tác trực tiếp với các đối tượng tạo nên giao diện người dùng ở những nơi cần thiết.
Ngay khi bạn bắt đầu đặt mã đưa ra quyết định về cách ứng dụng của bạn hoạt động trong đó có xu hướng dẫn đến sự cố.
Không chỉ logic ứng dụng có thể chảy vào mã được cho là liên quan đến giao diện người dùng, một số nhà phát triển bắt đầu dựa vào các điều khiển và các đối tượng giao diện người dùng khác để giữ trạng thái ứng dụng quan trọng.
Mô hình chỉ đơn giản là giữ dữ liệu, khung nhìn chỉ giữ ngày được định dạng và bộ điều khiển (ViewModel) đóng vai trò là liên lạc viên giữa hai mô hình. Bộ điều khiển có thể lấy đầu vào từ khung nhìn và đặt nó trên mô hình và ngược lại.
Bản trình bày riêng biệt
Để tránh các sự cố do đặt logic ứng dụng trong mã phía sau hoặc XAML, tốt nhất là sử dụng một kỹ thuật được gọi là separated presentation. Có XAML và mã phía sau với yêu cầu tối thiểu để làm việc trực tiếp với các đối tượng giao diện người dùng, một lớp giao diện người dùng cũng chứa mã cho các hành vi tương tác phức tạp, logic ứng dụng và mọi thứ khác như được hiển thị bên dưới bên trái.
Các tính năng quan trọng của Bản trình bày riêng -
Với cách trình bày riêng biệt, lớp giao diện người dùng đơn giản hơn nhiều. Tất nhiên, nó có XAML, nhưng mã đằng sau ít thực tế.
Logic ứng dụng thuộc về một lớp riêng biệt, thường được gọi là model.
Nhiều nhà phát triển cố gắng sử dụng liên kết dữ liệu để kết nối các phần tử trong XAML trực tiếp với các thuộc tính trong mô hình.
Vấn đề là model hoàn toàn quan tâm đến các vấn đề ứng dụng hoạt động chứ không phải cách người dùng tương tác với ứng dụng.
Hầu hết các giao diện người dùng có một số trạng thái không thuộc mô hình ứng dụng. Ví dụ: nếu giao diện người dùng của bạn sử dụng tính năng kéo và thả, cần theo dõi những thứ như vị trí mục đang được kéo ngay bây giờ, hình thức của nó sẽ thay đổi như thế nào khi nó di chuyển qua các mục tiêu thả có thể và cách các mục tiêu thả đó cũng có thể thay đổi khi mục được kéo qua chúng.
Loại trạng thái này có thể trở nên phức tạp đáng ngạc nhiên và cần được kiểm tra kỹ lưỡng.
Trong thực tế, bạn thường muốn một số lớp khác nằm giữa giao diện người dùng và mô hình. Điều này có hai vai trò quan trọng.
Đầu tiên, nó điều chỉnh mô hình ứng dụng của bạn cho một giao diện người dùng cụ thể.
Thứ hai, nó là nơi mà bất kỳ logic tương tác tầm thường nào tồn tại và theo đó, ý tôi là mã cần thiết để giao diện người dùng của bạn hoạt động theo cách bạn muốn.
Model / View / ViewModel
View Modellà một ví dụ về cách tiếp cận bản trình bày riêng biệt, nhưng chúng ta hãy nói rõ về loại thứ mà chúng ta có trong mỗi lớp. Có ba lớp -
- Model
- View
- ViewModel
Mô hình
Đây là một classic mô hình đối tượng bao gồm các lớp C # thông thường không có mối quan hệ trực tiếp với giao diện người dùng.
Bạn thường mong đợi Mã mẫu của mình có thể biên dịch mà không cần tham chiếu đến bất kỳ thư viện giao diện người dùng nào. Trên thực tế, bạn có thể lấy cùng một mã nguồn chính xác và biên dịch nó thành ứng dụng Silverlight, ứng dụng .NET Console thông thường hoặc thậm chí là mã web phía máy chủ.
Các kiểu trong Mô hình phải đại diện cho các khái niệm mà ứng dụng của bạn hoạt động.
Lượt xem
Chế độ xem thường là UserControl, nó có thể là Trang chính của bạn hoặc nó có thể chỉ là một phần nào đó trên trang của bạn.
Trong hầu hết các ứng dụng Silverlight, bạn nên chia giao diện người dùng của mình thành các phần nhỏ để xác định UserControl hoặc Chế độ xem cho từng phần.
Các ứng dụng Silverlight không phải là duy nhất về mặt này. Một thứ rõ ràng là Silverlight cụ thể là Chế độ xem. Giao diện người dùng của bạn càng chi tiết, mọi thứ càng có xu hướng tốt hơn. Bạn không chỉ ít có khả năng vượt qua các nhà phát triển khác làm việc trên cùng các tệp, việc giữ cho mọi thứ nhỏ và đơn giản tự nhiên không khuyến khích các phím tắt dẫn đến mã giống như mì Ý.
Ví dụ, rất phổ biến khi định nghĩa một View đại diện cho một mục riêng lẻ trong một Danh sách.
ViewModel
Cuối cùng, đối với mỗi View, bạn viết một ViewModel. Vì vậy, đây là một trong những tính năng quan trọng củaViewModel lớp học.
Nó tồn tại để phục vụ một Chế độ xem cụ thể. CácViewModel được chuyên dụng cho một cách trình bày mọi thứ cụ thể, chẳng hạn như một mục dữ liệu cụ thể khi nó xuất hiện trong Danh sách.
Đây là lý do tại sao nó được gọi là ViewModel; nó điều chỉnh Mô hình cơ bản đặc biệt cho một Chế độ xem cụ thể. Giống như Mô hình,ViewModelcũng là một lớp C # bình thường. Nó không cần bắt nguồn từ bất kỳ loại cụ thể nào.
Khi nó xảy ra, một số nhà phát triển thấy thuận tiện khi đưa một số chức năng phổ biến vào lớp ViewModel cơ sở, nhưng mẫu không yêu cầu điều đó. Đặc biệt, của bạnViewModelkhông bắt nguồn từ bất kỳ loại Silverlight cụ thể nào. Tuy nhiên, không giống như mô hình, nó có thể sử dụng các loại Silverlight trong các thuộc tính của nó.
Ví dụ: ViewModel của bạn có thể chọn làm cho một số phần nhất định của giao diện người dùng của bạn chỉ hiển thị trong một số điều kiện nhất định và do đó, bạn có thể cung cấp thuộc tính kiểu System.Windows.Visibility, là loại phần tử Silverlight sử dụng cho thuộc tính Visibility của chúng. Điều này giúp bạn có thể liên kết khả năng hiển thị của một phần tử, chẳng hạn như bảng điều khiển, trực tiếp với ViewModel.
Thí dụ
Chúng ta hãy xem một ví dụ đơn giản mà chúng ta sẽ sử dụng Model-View-ViewModel (MVVM) tiếp cận.
Step 1 - Tạo một dự án Ứng dụng Silverlight mới SilverlightMVVMDemo.
Step 2 - Thêm ba thư mục (Model, ViewModel và Views) vào dự án của bạn như hình dưới đây.
Step 3 - Thêm một lớp StudentModel trong thư mục Model và dán đoạn mã dưới đây vào lớp đó.
using System.ComponentModel;
namespace SilverlightMVVMDemo.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));
}
}
}
}
Step 4 - Thêm một lớp StudentViewModel khác vào thư mục ViewModel và dán đoạn mã sau.
using SilverlightMVVMDemo.Model;
using System.Collections.ObjectModel;
namespace SilverlightMVVMDemo.ViewModel {
public class StudentViewModel {
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;
}
}
}
Step 5 - Thêm Silverlight User Control bằng cách nhấp chuột phải vào Views thư mục và Chọn Add New Item….
Step 6- Nhấp vào Thêm. Bây giờ bạn sẽ thấy tệp XAML. Thêm mã sau vàoStudentView.xaml tệp chứa các phần tử giao diện người dùng khác nhau.
<UserControl x:Class = "SilverlightMVVMDemo.Views.StudentView"
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"
mc:Ignorable = "d"
d:DesignHeight = "300" d:DesignWidth = "400">
<Grid x:Name = "LayoutRoot" Background = "White">
<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>
Step 7 - Bây giờ thêm StudentView vào của bạn MainPage.xaml tập tin như hình dưới đây.
<UserControl x:Class = "SilverlightMVVMDemo.MainPage"
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:views = "clr-namespace:SilverlightMVVMDemo.Views"
mc:Ignorable = "d"
d:DesignHeight = "576.316" d:DesignWidth = "863.158">
<Grid x:Name = "LayoutRoot" Background = "White">
<views:StudentView x:Name = "StudentViewControl" Loaded = "StudentViewControl_Loaded"/>
</Grid>
</UserControl>
Step 8 - Đây là việc thực hiện Loaded sự kiện trong MainPage.xaml.cs tệp này sẽ cập nhật View từ ViewModel.
using System.Windows;
using System.Windows.Controls;
namespace SilverlightMVVMDemo {
public partial class MainPage : UserControl {
public MainPage() {
InitializeComponent();
}
}
private void StudentViewControl_Loaded(object sender, RoutedEventArgs e) {
SilverlightMVVMDemo.ViewModel.StudentViewModel
studentViewModelObject = new SilverlightMVVMDemo.ViewModel.
StudentViewModel();
studentViewModelObject.LoadStudents();
StudentViewControl.DataContext = studentViewModelObject;
}
}
Step 9 - Khi đoạn mã trên được biên dịch và thực thi, bạn sẽ thấy kết quả sau trên trang web của mình.
UI so với ViewModel
Một trong những phần khó nhất của phương pháp MVVM là tìm ra ranh giới nên đến. Không phải lúc nào cũng rõ ràng thứ nào thuộc về nơi nào.
Đặc biệt, một số thành phần giao diện người dùng cung cấp chức năng, theo một Chế độ xem nghiêm ngặt, được cho là thuộc về ViewModel.
Nói chung, không phải tất cả các hành vi được thực hiện trong View rất là ViewModel thân thiện.
Một phần của lý do này là không có bất kỳ cách tiêu chuẩn nào để đóng gói hành vi ViewModel để sử dụng lại, đặc biệt là không nếu bạn muốn sử dụng môi trường thiết kế, chẳng hạn như Visual Studio hoặc Blend.
Ưu điểm của MVVM
MVVM cung cấp những ưu điểm sau:
Tách các mối quan tâm về bản trình bày (View, ViewModel, Model)
Làm sạch mã có thể kiểm tra và quản lý được. Có thể bao gồm logic bậc trình bày trong kiểm thử đơn vị.
Không có mã phía sau mã, vì vậy lớp trình bày và logic được kết hợp lỏng lẻo.
Cách tốt hơn để kết hợp dữ liệu.
Nhược điểm của MVVM
Đối với giao diện người dùng đơn giản, MVVM có thể quá mức cần thiết. Gỡ lỗi sẽ hơi khó khăn khi chúng ta có các ràng buộc dữ liệu phức tạp.