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
- WPF Apps With The Model-View-ViewModel Design Pattern
- Data Validation in .NET 3.5
- Using a ViewModel to Provide Meaningful Validation Error Messages
- Action based ViewModel and Model validation
- Dialogs
- Command Bindings in MVVM
- More than just MVC for WPF
- MVVM Mediator Example Application
Ekran
Ek Kütüphaneler
- WPF Disciples' improved Mediator Pattern implementation(ben çok daha karmaşık olan uygulamalar için bu tavsiye navigasyon)
- MVVM Light Toolkit Messenger
CEVAP
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.
Tek örnek bir uygulama oluşturmak için...
Şablon oluşturma kolaylaştırmak için J...
Nasıl bir şablon motoru olarak undersc...
Nasıl olursa underscore.js ifadeleri b...
Nasıl hata ayıklama KnockoutJS için ba...