MVVM - WPF Veri Şablonları
Bir şablon, kontrolün genel görünümünü ve görsel görünümünü tanımlar. Her kontrol için, bu kontrole görünüm veren, kendisiyle ilişkilendirilmiş varsayılan bir şablon vardır. WPF uygulamasında, bir kontrolün görsel davranışını ve görsel görünümünü özelleştirmek istediğinizde kendi şablonlarınızı kolayca oluşturabilirsiniz. Mantık ve şablon arasındaki bağlantı, veri bağlama ile sağlanabilir.
MVVM'de, ViewModel ilk yapısı olarak bilinen başka bir birincil form vardır.
ViewModel'in ilk yapım yaklaşımı, WPF'deki örtük veri şablonlarının yeteneklerinden yararlanır.
Örtük veri şablonları, veri bağlamayı kullanan bir öğe için geçerli kaynak sözlüğünden uygun bir şablonu otomatik olarak seçebilir. Bunu, veri bağlama ile oluşturulan veri nesnesinin türüne göre yaparlar. Öncelikle, bir veri nesnesine bağlanan bazı öğelere sahip olmanız gerekir.
Öncelikle veri şablonlarını, özellikle örtük veri şablonlarını kullanarak modeli nasıl görüntüleyebileceğinizi anlayacağınız basit örneğimize tekrar bir göz atalım. İşte StudentViewModel sınıfımızın uygulaması.
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;
}
}
}
Yukarıdaki ViewModel'in değişmediğini görebilirsiniz. Bir önceki bölümden aynı örnekle devam edeceğiz. Bu ViewModel sınıfı, Students collection özelliğini ortaya çıkarır ve onu yapım aşamasında doldurur. StudentView.xaml dosyasına gidelim, mevcut uygulamayı kaldıralım ve Kaynaklar bölümünde bir veri şablonu tanımlayalım.
<UserControl.Resources>
<DataTemplate x:Key = "studentsTemplate">
<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>
</UserControl.Resources>
Şimdi bir liste kutusu ekleyin ve bu liste kutusunu aşağıdaki kodda gösterildiği gibi Öğrenciler özelliğine bağlayın.
<ListBox ItemsSource = "{Binding Students}" ItemTemplate = "{StaticResource studentsTemplate}"/>
Kaynak bölümünde, DataTemplate bir studentTemplate anahtarına sahiptir ve daha sonra bu şablonu gerçekten kullanmak için bir ListBox öğesinin ItemTemplate özelliğini kullanmamız gerekir. Şimdi, liste kutusuna o Öğrencileri işlemek için o belirli şablonu kullanması talimatını verdiğimizi görebilirsiniz. StudentView.xaml dosyasının tam uygulaması aşağıdadır.
<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.Resources>
<DataTemplate x:Key = "studentsTemplate">
<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>
</UserControl.Resources>
<Grid>
<ListBox
ItemsSource = "{Binding Students}"
ItemTemplate = "{StaticResource studentsTemplate}"/>
</Grid>
</UserControl>
Yukarıdaki kod derlendiğinde ve çalıştırıldığında, bir ListBox içeren aşağıdaki pencereyi göreceksiniz. Her ListBoxItem, TextBlock ve Text kutularında görüntülenen Student sınıfı nesne verilerini içerir.
Bunu örtük bir şablon yapmak için, ItemTemplate özelliğini bir liste kutusundan kaldırmamız ve aşağıdaki kodda gösterildiği gibi şablon tanımımıza bir DataType özelliği eklememiz gerekir.
<UserControl.Resources>
<DataTemplate DataType = "{x:Type data:Student}">
<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>
</UserControl.Resources>
<Grid>
<ListBox ItemsSource = "{Binding Students}"/>
</Grid>
DataTemplate'te, x: Type işaretleme uzantısı çok önemlidir, bu da XAML'deki bir operatör türü gibidir. Bu nedenle, temel olarak MVVMDemo.Model ad alanında bulunan Öğrenci veri türüne işaret etmemiz gerekir. Aşağıda güncellenmiş tam XAML dosyası verilmiştir.
<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:data = "clr-namespace:MVVMDemo.Model"
xmlns:vml = "clr-namespace:MVVMDemo.VML"
vml:ViewModelLocator.AutoHookedUpViewModel = "True"
mc:Ignorable = "d" d:DesignHeight = "300" d:DesignWidth = "300">
<UserControl.Resources>
<DataTemplate DataType = "{x:Type data:Student}">
<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>
</UserControl.Resources>
<Grid>
<ListBox ItemsSource = "{Binding Students}"/>
</Grid>
</UserControl>
Bu uygulamayı tekrar çalıştırdığınızda, uygun DataTemplate'i bularak oluşturulan nesnenin türünü otomatik olarak eşleştirdiği için, Öğrenciler ile veri şablonunun aynı işlemesini yine de alacaksınız.
Daha iyi anlamak için yukarıdaki örneği adım adım uygulamanızı öneririz.