SORU
2 Kasım 2009, PAZARTESİ


MVVM Şablon için iyi bir örnek

Şu anda Microsoft MVVM şablonu ile çalışıyorum ve ayrıntılı örnekler eksikliği sinir bozucu buluyor. Verilen ContactBook örnek gösterir çok az Komut işleme ve tek bir örnek buldum. bir MSDN Magazine makale nerede kavramlardır benzer kullanır ama biraz farklı bir yaklaşım ve hala eksikliği herhangi bir karmaşıklık. En azından temel CRUD işlemleri ve iletişim/gösteren örnekler herhangi bir iyi MVVM içerik geçiş var mı?


Herkesin önerileri çok yararlı ve iyi kaynakların bir listesini derlemek başlayacak

Çerçeveler/Şablonlar

Yararlı Makaleler

Ekran

Ek Kütüphaneler

CEVAP
10 Kasım 2009, Salı


Ne yazık ki bu her şeyi yapar app büyük bir MVVM örnek olarak bir yerlerde bir şeyler yapmak için başka bir yaklaşım var. Öncelikle isteyebilirsiniz aşina bir uygulama çerçeveleri dışarıda (Prizma iyi bir seçim), çünkü onlar size uygun araçlar gibi bağımlılık enjeksiyon, komuta, olay toplama, vb kolayca denemek farklı desen o takımı.

Prizma serbest:
http://www.codeplex.com/CompositeWPF

Çok iyi örnek bir uygulama (hisse senedi tüccar) için küçük örnekler bir sürü ile birlikte ve nasıl içerir. En azından alt desen insanlar MVVM aslında iş yapmak için birkaç genel kullanım için güzel bir tanıtım. Hem CRUD ve diyaloglar için örnekler var, inanıyorum.

Prizma mutlaka her proje için değil, ama tanımak için iyi bir şey.

CRUD: Bu bölümü iki şekilde bağlamaları gerçekten kolay en verileri düzenlemek için yapmak çok kolay, WPF. Gerçek kandırmak kolay UI ayarlamak için yapan bir model sunmaktır. En azından istediğiniz emin olmak için senin ViewModel (veya iş nesnesi) uygular INotifyPropertyChanged destek bağlama ve bağlama özellikleri düz UI kontrolleri, ama bir kısmı aynı zamanda uygulamak IDataErrorInfo doğrulama. Eğer ORM çözümü bir çeşit kullanırsanız genellikle CRUD kurmak çok kolay.

Bu makalede, basit crud işlemleri gösterir: http://dotnetslackers.com/articles/wpf/WPFDataBindingWithLINQ.aspx

LinqToSql üzerine inşa edilmiştir, ama bu örnek - önemli olan tüm iş nesneleri INotifyPropertyChanged sınıflar LinqToSql tarafından oluşturulan) uygulamak için bir önemi yok. MVVM bu örnek değil, ama bu durumda bir önemi olduğunu sanmıyorum.

Bu makalede, Veri Doğrulama gösterir
http://blogs.msdn.com/wpfsdk/archive/2007/10/02/data-validation-in-3-5.aspx

Yine, en ORM çözümleri zaten IDataErrorInfo uygulayan sınıflar oluşturmak ve genellikle kolay özel geçerlilik kuralları eklemek için yapmak için bir mekanizma sağlar.

Çoğu zaman sen-ebilmek almak bir nesne(model) tarafından oluşturulan bazı ORM ve sarma bir ViewModel tutar ve komutları için Kaydet/Sil - ve sen hazır bağlamak UI düz modeli özellikleri.

Görünümü böyle bir model, bir sınıf ORM oluşturulan gibi tutan 10 ** bir özelliği var ViewModel () gibi görünecektir:

<StackPanel>
   <StackPanel DataContext=Item>
      <TextBox Text="{Binding FirstName, Mode=TwoWay, ValidatesOnDataErrors=True}" />
      <TextBox Text="{Binding LastName, Mode=TwoWay, ValidatesOnDataErrors=True}" />
   </StackPanel>
   <Button Command="{Binding SaveCommand}" />
   <Button Command="{Binding CancelCommand}" />
</StackPanel>

Diyaloglar: Diyaloglar ve MVVM biraz zor. Diyaloglar ile Arabuluculuk yaklaşımının bir lezzet kullanmayı tercih ediyorum, biraz daha bu StackOverflow soru bu konuda okuyabilirsiniz:
WPF MVVM dialog example

Oldukça klasik MVVM olan benim her zamanki yaklaşımı aşağıdaki gibi özetlenebilir

Bir temel sınıf için bir iletişim ViewModel sunar komutları için taahhüt ve iptal eylemler için bir olay sağlar görünümü bir iletişim hazır kapalı ve ne olursa olsun ihtiyacınız olacak tüm diyaloglar.

İletişim için genel bir görünüm - bu bir pencere olabilir, ya da özel bir "kalıcı" kaplama türü kontrol. Onun kalbi bir içerik sunan bu biz döküm viewmodel ve işleme tesisatı için kapanış pencere - örneğin veri içeriği değiştirebilirsiniz kontrol ederseniz yeni ViewModel devralınan temel sınıf, ve eğer, abone olmak için ilgili yakın olay işleyicisi olacak ata iletişim sonucu). Eğer alternatif evrensel işlevsellik (X düğmesine mesela) yakın sağlarsanız, ViewModel ilgili Kapat komutu çalıştırmak için emin olarak yapmak gerekir.

Senin ViewModels için veri şablonları sağlamanız gereken bir yer, özellikle de muhtemelen her iletişim ayrı bir kontrol saklanmış bir görünüm var, çünkü bu çok basit olabilir. Varsayılan veri ViewModel için şablon sonra bu gibi bir şey olacaktır

<DataTemplate DataType="{x:Type vmodels:AddressEditViewModel}>
   <views:AddressEditView DataContext={Binding} />
</DataTemplate>

İletişim görüntüleyin aksi ViewModel göstermek için nasıl bilmiyor çünkü bu erişimi olması gerekir, paylaşılan iletişim UI dışında onun içindekiler bu temelde:

<ContentControl Content={Binding} />

Örtülü veri şablonu başlatan model görünümü göster, ama olacak?

Bu pek mvvm parçasıdır. Bunu yapmanın bir yolu, küresel bir olay kullanmaktır. Yapacak daha iyi bir şey olduğunu düşündüğüm bir olay türü Kur, bağımlılık enjeksiyon yoluyla sağlanan olay kapsayıcı, tüm uygulama değil, genel olarak bu şekilde toplayıcı kullanın. Prizma konteyner anlambilim ve bağımlılık enjeksiyon için birlik çerçevesinde kullanır ve genel Birlik bir hayli severim.

Genellikle, kök penceresinde bu olay, abone olmak için mantıklı - iletişim ve gündeme bir olay ile geçirilen alır ViewModel veri içeriği ayarlayabilirsiniz.

Bu şekilde ayarlama çoğunlukla MVVM-ness tamamlamak kalır ViewModels uygulama bir iletişim kutusu açmak için sormak ve UI hakkında hiçbir şey bilmeden kullanıcı eylemleri için orada yanıt verir.

UI işler biraz yanıltıcıdır yapabilirsiniz diyaloglar, yetiştirmeli zamanlar, ancak vardır. Eğer iletişim pozisyon açıldığında düğmesini konumuna bağlıdır, örneğin, düşünün. Bu durumda bir iletişim açmak istediğinde bazı UI özel bilgi olması gerekir. Ben genellikle bir ViewModel ve bazı UI ilgili bilgi tutan ayrı bir sınıf oluşturun. Ne yazık ki bazı kaplin kaçınılmaz gözüküyor.

Eleman pozisyon bilgisi gereken bir iletişim başlatan bir düğme işleyicisi Pseudo kodu

ButtonClickHandler(sender, args){
    var vm = DataContext as ISomeDialogProvider; // check for null
    var ui_vm = new ViewModelContainer();
    // assign margin, width, or anything else that your custom dialog might require
    ...
    ui_vm.ViewModel = vm.SomeDialogViewModel; // or .GetSomeDialogViewModel()
    // raise the dialog show event
}

İletişim görüntüleyin pozisyon verilere bağlamak, ve iç için bulunan ViewModel ContentControl geçecek. Bu ViewModel kendisi hala UI hakkında hiçbir şey bilmiyor.

Genel olarak iletişim kapanana kadar ShowDialog() yöntem veya iş parçacığı bloke bekliyoruz DialogResult dönüş özelliği kullanmak istemiyorum. Standart olmayan kalıcı bir iletişim kutusu her zaman bu şekilde çalışmaz, ve kompozit bir ortamda sık sık gerçekten bir olay bu nasıl engelleme işleyicisi istemiyorum. Ben tercih için izin ViewModels anlaşma ile bu yaratıcının bir ViewModel olabilir abone olmak için onun konu ile ilgili olaylar, set kaydetme/iptal yöntemleri, vb, bu yüzden gerek yoktur güveniyor bu UI mekanizması.

Yani, bu akışın yerine:

// in code behind
var result = somedialog.ShowDialog();
if (result == ...

Ben kullanın:

// in view model
var vm = new SomeDialogViewModel(); // child view model
vm.CommitAction = delegate { this.DoSomething(vm); } // what happens on commit 
vm.CancelAction = delegate { this.DoNothing(vm); } // what happens on cancel/close (optional)
// raise dialog request event on the container

Benim diyaloglar en engellenmeyen sözde mod kontrolleri de vardır ve bunu bu şekilde yapmak etrafında çalışmak daha kolay görünüyor çünkü böyle olmasını tercih ederim. Kolay bir test olarak ünite için.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Adam Khoury

    Adam Khoury

    23 Ocak 2008
  • theavettbrothers

    theavettbrot

    9 ŞUBAT 2007
  • Videojug

    Videojug

    25 EKİM 2006