Görünüm modeli kullanma
MVVM desenini oluşturan bileşenler hakkında bilgi edindikten sonra büyük olasılıkla modelin ve görünümün tanımlanmasının kolay olduğunu fark etmişsinizdir. Şimdi modeldeki rolünü daha iyi tanımlamak için görünüm modelini nasıl kullanacağınızı inceleyelim.
Özellikleri kullanıcı arabiriminde kullanıma sunma
Önceki örnekte olduğu gibi görünüm modelleri genellikle verilerinin çoğuna ve herhangi bir iş mantığına yönelik modelleri kullanır. Ancak verileri geçerli görünümün gerektirdiği şekilde biçimlendiren, dönüştüren ve zenginleştiren görünüm modelidir.
Görünüm modeli kullanarak biçimlendirme
Tatil zamanına sahip biçimlendirmenin bir örneğini zaten gördünüz. Tarih biçimlendirme, karakter kodlama ve serileştirme, görünüm modelinin modelden verileri nasıl biçimlendirebileceğine ilişkin tüm örneklerdir.
Görünüm modeli kullanarak dönüştürme
Genellikle, model dolaylı yollarla bilgi sağlar. Ancak görünüm modeli bunu düzeltebilir. Örneğin, bir çalışanın gözetmen olup olmadığını ekranda göstermek istediğinizi varsayalım. Ancak modelimiz Employee
bunu doğrudan bize söylemiyor. Bunun yerine, bu gerçeği, kişinin kendilerine rapor eden başkaları olup olmadığına bağlı olarak çıkarabilirsiniz. Modelin şu özelliğe sahip olduğunu varsayın:
public IList<Employee> DirectReports
{
get
{
...
}
}
Liste boşsa, bunun Employee
bir gözetmen olmadığını çıkarabilirsiniz. Bu durumda, EmployeeViewModel
bu mantığı sağlayan özelliği IsSupervisor
içerir:
public bool IsSupervisor => _model.DirectReports.Any();
Görünüm modeli kullanarak zenginleştirme
Bazen model yalnızca ilgili veriler için kimlik sağlayabilir. Ya da tek bir ekran için gereken verileri ilişkilendirmek için birkaç model sınıfına gitmeniz gerekebilir. Görünüm modeli, bu görevleri gerçekleştirmek için de ideal bir yer sağlar. Bir çalışanın yönetmekte olduğu tüm projeleri göstermek istediğinizi varsayalım. Bu veriler model sınıfının bir parçası Employee
değildir. Model sınıfına bakılarak CompanyProjects
erişilebilir. her zaman olduğu gibi bizim EmployeeViewModel
çalışmamızı genel bir özellik olarak kullanıma sunar:
public IEnumerable<string> ActiveProjects => CompanyProjects.All
.Where(p => p.Owner == _model.Id && p.IsActive)
.Select(p => p.Name);
Görünüm modeliyle geçiş özelliklerini kullanma
Bir görünüm modelinin genellikle tam olarak modelin sağladığı özelliğe ihtiyacı vardır. Bu özellikler için görünüm modeli verileri şu şekilde geçirir:
public string Name
{
get => _model.Name;
set => _model.Name = value;
}
Görünüm modeli için kapsamı ayarlama
Görünümün bulunduğu herhangi bir düzeyde görünüm modeli kullanabilirsiniz. Bir sayfanın genellikle bir görünüm modeli vardır , ancak sayfanın alt görünümleri de olabilir. İç içe görünüm modellerinin yaygın nedenlerinden biri, sayfanın sayfada bir ListView
görüntülemesidir. Listede koleksiyonu temsil eden bir görünüm modeli vardır, örneğin EmployeeListViewModel
. Listedeki her öğe bir EmployeeViewModel
öğesidir.
Ayrıca, uygulamanın tamamı için verileri ve durumu tutan ancak belirli bir sayfayla ilişkili olmayan üst düzey bir görünüm modeline sahip olmak da yaygındır. Böyle bir görünüm modeli genellikle "etkin" öğeyi korumak için kullanılır. ListView
Az önce açıklanan örneği göz önünde bulundurun. Kullanıcı bir çalışan satırı seçtiğinde, bu çalışan geçerli maddeyi temsil eder. Kullanıcı bir ayrıntı sayfasına giderse veya bu satır seçiliyken bir araç çubuğu düğmesi seçerse, eylem veya görüntü söz konusu çalışana yönelik olmalıdır. Bu senaryoyu işlemenin zarif bir yolu, verilerin araç çubuğunun ListView.SelectItem
veya ayrıntı sayfasının da erişebileceği bir özelliğe bağlı olmasıdır. Bu özelliği merkezi bir görünüm modeline yerleştirmek iyi çalışır.
Görünüm modellerinin görünümlerle ne zaman yeniden kullanılacaını belirleme
Görünüm modeli ve model ile görünüm modeli arasındaki ilişkiyi nasıl tanımladığınız, kurallara göre uygulama gereksinimlerine göre daha fazla dikte edilir. Görünüm modelinin amacı, görünüme ihtiyaç duyduğu yapıyı ve verileri sağlamaktır. Bu, görünüm modellerinin kapsamının "ne kadar büyük" olduğuna ilişkin kararlara yol göstermelidir.
Görünüm modelleri genellikle bir model sınıfının yapısını yakından yansıtır ve bu sınıfla bire bir ilişkisi vardır. Daha önce EmployeeViewModel
tek Employee
bir örneği sarmalayan ve genişleten bir örnek gördünüz. Ama bu her zaman bire bir ilişki değildir. Görünüm modeli görünümün ihtiyaçlarını sağlayacak şekilde tasarlandıysa, bunun yerine herhangi bir modelle açık bir ilişkisi olmayan ancak herhangi bir model sınıfındaki verileri kullanabilen bir İk departmanına genel bakış sağlamak gibi HRDashboardViewModel
bir şey elde edebilirsiniz.
Benzer şekilde, görünüm modellerinin ve görünümlerin genellikle bire bir ilişkisi olduğunu fark edebilirsiniz. Ancak bu durum aynı zamanda geçerli olmayabilir. Her çalışan için bir satır gösteren bir ListView
yeniden düşünelim. Satırlardan birini seçtiğinizde, çalışan ayrıntıları sayfasına gidersiniz.
Liste sayfasında bir koleksiyona sahip görünüm modeli vardır. Daha önce de önerileceği gibi, bu koleksiyon bir nesne koleksiyonu EmployeeViewModel
olabilir. Kullanıcı bir satır seçtiğindeEmployeeViewModel
, örneği öğesine EmployeeDetailPage
geçirilebilir. Ayrıntı sayfası bunu EmployeeViewModel
olarak BindingContext
kullanabilir.
Bu senaryo , görünüm modeli yeniden kullanımı için mükemmel bir fırsat olabilir . Ancak görünüm modellerinin görünümün ihtiyaçlarını karşılamaya yönelik olduğunu unutmayın. Bazı durumlarda, hepsi aynı model sınıfına dayalı olsa bile ayrı görünüm modelleri isteyebilirsiniz. Bu örnekte, satırların ListView
tam ayrıntı sayfasından çok daha az bilgiye ihtiyacı vardır. Ayrıntı sayfasının ihtiyaç duyduğu verileri almak ek yük getirirse, bu ilgili görünümlere hizmet veren hem hem EmployeeDetailViewModel
de EmployeeListRowViewModel
modellerine sahip olmak isteyebilirsiniz.
Görünüm modeli nesne modeli
Uygulayan INotifyPropertyChanged
bir temel sınıf kullanmak, arabirimi her görünüm modelinde yeniden oluşturmanız gerekmemesi anlamına gelir. bu eğitim modülünün önceki bölümünde açıklandığı gibi İk uygulamasını göz önünde bulundurun. EmployeeViewModel
sınıfı arabirimini INotifyPropertyChanged
uyguladı ve olayı yükseltmek PropertyChanged
için adlı OnPropertyChanged
bir yardımcı yöntem sağladı. Bir çalışana atanan kaynakları açıklayanlar gibi projedeki diğer görünüm modellerinin de bir görünümle tam olarak tümleştirilmesi gerekir INotifyPropertyChanged
.
.NET Community Toolkit'in bir parçası olan MVVM Toolkit kitaplığı, MVVM desenini kullanarak modern uygulamalar oluşturmaya yönelik başlangıç uygulaması sağlayan standart, bağımsız, basit türlerden oluşan bir koleksiyondur.
Kendi viewmodel temel sınıfınızı yazmak yerine, bir görünüm modeli temel sınıfı için ihtiyacınız olan her şeyi sağlayan araç setinin ObservableObject
sınıfından devralırsınız. EmployeeViewModel
şu kaynaklardan basitleştirilmiş olabilir:
using System.ComponentModel;
public class EmployeeViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;
private Employee _model;
public string Name
{
get {...}
set
{
_model.Name = value;
OnPropertyChanged(nameof(Name))
}
}
protected void OnPropertyChanged(string propertyName) =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
Aşağıdaki koda:
using Microsoft.Toolkit.Mvvm.ComponentModel;
public class EmployeeViewModel : ObservableObject
{
private string _name;
public string Name
{
get => _name;
set => SetProperty(ref _name, value);
}
}
MVVM Araç Seti, NuGet paketi aracılığıyla CommunityToolkit.Mvvm
dağıtılır.