MVVM - การเพิ่มมุมมอง

ในบทนี้เราจะกล่าวถึงวิธีต่างๆที่คุณสามารถทำให้มุมมองของคุณเชื่อมต่อกับ ViewModel ก่อนอื่นมาดูที่ View first construction ซึ่งเราสามารถประกาศใน XAML ดังที่เราได้เห็นตัวอย่างในบทสุดท้ายที่เราได้เชื่อมต่อมุมมองจากหน้าต่างหลัก ตอนนี้เราจะเห็นวิธีอื่น ๆ ในการเชื่อมต่อมุมมอง

เราจะใช้ตัวอย่างเดียวกันในบทนี้ด้วย ต่อไปนี้เป็นการใช้งานคลาส Model เดียวกัน

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
  • ดูการก่อสร้างครั้งแรกใน Code-behind

ดูโครงสร้างแรกใน XAML

วิธีหนึ่งคือเพียงเพิ่ม ViewModel ของคุณเป็นองค์ประกอบที่ซ้อนกันใน setter สำหรับคุณสมบัติ DataContext ดังแสดงในโค้ดต่อไปนี้

<UserControl.DataContext> 
   <viewModel:StudentViewModel/> 
</UserControl.DataContext>

นี่คือไฟล์ View 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>

ดูการก่อสร้างครั้งแรกใน Code-behind

อีกวิธีหนึ่งคือคุณสามารถรับโครงสร้าง View first ได้โดยเพียงแค่สร้างโมเดลมุมมองด้วยตัวเองในโค้ดด้านหลัง View ของคุณโดยตั้งค่าคุณสมบัติ DataContext ที่นั่นด้วยอินสแตนซ์

โดยทั่วไปคุณสมบัติ DataContext จะถูกตั้งค่าในเมธอดคอนสตรัคเตอร์ของมุมมอง แต่คุณยังสามารถเลื่อนการสร้างได้จนกว่าเหตุการณ์โหลดของมุมมองจะเริ่มทำงาน

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(); 
      } 
   } 
}

เหตุผลหนึ่งในการสร้างโมเดลมุมมองใน Code-behind แทนที่จะเป็น XAML คือตัวสร้างโมเดล View รับพารามิเตอร์ แต่การแยกวิเคราะห์ XAML สามารถสร้างองค์ประกอบได้หากกำหนดไว้ในตัวสร้างเริ่มต้นเท่านั้น

ในกรณีนี้ไฟล์ XAML ของ View จะมีลักษณะดังที่แสดงในโค้ดต่อไปนี้

<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>

คุณสามารถประกาศ View นี้ใน 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>

เมื่อโค้ดด้านบนถูกคอมไพล์และดำเนินการคุณจะเห็นผลลัพธ์ต่อไปนี้ในหน้าต่างหลักของคุณ

เราขอแนะนำให้คุณดำเนินการตามตัวอย่างข้างต้นในลักษณะทีละขั้นตอนเพื่อความเข้าใจที่ดีขึ้น