2009-03-16 11 views

cevap

22

Fark, RelayCommand'ın temsilci kabul edebileceğidir. ReMitCommand'ı ViewModel'in dışından tanımlayabilirsiniz. Daha sonra ViewModel, komutu bir komut gibi bir UI nesnesine oluşturduğunda ve komut verdiğinde komutlara temsilci ekleyebilir. Delegeler, ViewModel'in özel değişkeni Görünüm Modelinin kendisinde tanımlandığı gibi erişebilir.

Bu, ViewModel içinde iç içe geçmiş bir sınıf olarak Yöneltilmiş bir komut tanımlamak eğilim olduğundan ViewModel'de bulunan kod miktarını azaltmak için kullanılır. İkisinin işlevselliği başka türlü benzerdir.

67

RoutedCommand, WPF'nin bir parçasıdır; RelayCommand, bir WPF Disciple, Josh Smith;) tarafından oluşturuldu.

Ancak RS Conley bazı farklılıkları açıkladı. En önemli fark, RoutedCommand'ın komut için bir CommandBinding bulunana kadar bir RoutedEvent öğesini kullanarak bir Router komutunu kullanmasıdır. RelayCommand yönlendirmeyi yapmaz ve bunun yerine bazı delege çalıştırır. Bir M-V-VM senaryosunda bir RelayCommand (Prism'deki DelegateCommand) muhtemelen daha iyi bir seçimdir. MVVM RelayCommand ve RoutedCommand kullanımı ile ilgili olarak

34

benim için temel fark şudur:

RelayCommand Eğer (herhangi bir sınıfta komutu uygulamak sağlayan kodun

Yer iCommand mülkü olarak delege ile), daha sonra konvansiyonu kontrol etmek için geleneksel olarak veriye aktarılır. Bu sınıf ViewModel'dur. Yöneltilmiş bir komut kullanırsanız, komutlar, KomutBinding öğesinin öznitelikleri tarafından belirtildiğinden, denetimin codebehind kodundaki ilgili yöntemleri uygulamalısınız. Sıkı MVVM'nin bir "boş" kod-kod-dosyaya sahip olduğu anlamına geldiği varsayılırsa, gerçekte MVVM ile standart yönlendirilmiş komutların kullanılması mümkün değildir.

Ne RS Conley RelayCommand Eğer ViewModel dışında RelayCommand haklı tanımlamanızı sağlar, ama her şeyden önce bunu içeride o RoutedCommand değil ViewModel, tanımlamak için izin verdiğini söyledi. Öte yandan Yönlendirme

, (daha önce söylediğim gibi) RelayCommands arayüz tek ViewModel dayanmaktadır sürece bir sorun değil, hangi ağacın üzerinden yönlendirmeyi desteklemez. Öyle değilse, örneğin kendi görünümü olan öğelerden oluşan bir koleksiyonunuz varsa ve ana öğenin her öğesinde bir kerede ViewModel komutunun bir komutunu çağırmak istiyorsanız, yönlendirmeyi kullanmanız gerekir (ayrıca bkz. CompositeCommands). .

Sonuç olarak, bu standart RoutedCommands katı MVVM'de kullanılamaz. RelayCommands MVVM için mükemmeldir, ancak ihtiyacınız olabilecek yönlendirmeyi desteklemez.

+0

Açıklamalarınızdaki ekstra derinlik ve CompositeCommands referansı için teşekkürler - bu, onların nereye yerleştiklerini görmeme yardımcı oldu. –

13

RoutedCommand'ların katı MVVM'de tamamen yasal olduğunu iddia ediyorum. RelayCommands genellikle sadelikleri için tercih edilmesine rağmen, RoutedCommands bazen organizasyonel avantajlar sunar.Örneğin, bu komutu doğrudan alttaki ViewModel'lere göstermeden paylaşılan bir ICommand örneğine bağlanmak için farklı görünümlerin olmasını isteyebilirsiniz. Bir yan not olarak, sıkı MVVM'nin kod arkasını kullanmasını engellemediğini unutmayın. Bu doğru olsaydı, görünümlerinizde asla özel bağımlılık özelliklerini tanımlayamazdınız!

  1. özel komutu için statik bir RoutedCommand örneği bildirin: Bu adımları takip edebilecek sıkı bir MVVM çerçevesinde RoutedCommand kullanmak için

    . ApplicationCommands sınıfından önceden tanımlanmış bir komut kullanmayı planlıyorsanız, bu adımı atlayabilirsiniz. Örneğin: ihtiyaçları (ViewModel komut işlevi uygulayan hangisi örneğin) uygun bir ViewModel bağlı görünümlerinizin

    <Button Command="{x:Static local:MyCommands.MyCustomCommand}" /> 
    
  2. biri:

    public static class MyCommands { 
        public static RoutedCommand MyCustomCommand = new RoutedCommand(); 
    } 
    
  3. RoutedCommand kullanılarak XAML istenen incelemeler takın senin ViewModel uygulamasına bağlı olacaktır özel bir DependencyProperty açığa çıkarmak için:

    public partial class MainView : UserControl 
    { 
        public static readonly DependencyProperty MyCustomCommandProperty = 
         DependencyProperty.Register("MyCustomCommand", 
         typeof(ICommand), typeof(MainView), new UIPropertyMetadata(null)); 
    
        public ICommand MyCustomCommand { 
         get { return (ICommand)GetValue(MyCustomCommandProperty); } 
         set { SetValue(MyCustomCommandProperty, value); } 
        } 
    
  4. Pe E Aynı görünüm XAML 1. adımda den RoutedCommand kendisini bağlamak gerekir:

    <UserControl.CommandBindings> 
        <CommandBinding Command="{x:Static local:MyCommands.MyCustomCommand}" 
            CanExecute="MyCustomCommand_CanExecute" 
            Executed="MyCustomCommand_Executed" 
            /> 
    </UserControl.CommandBindings> 
    

    yılında kod arkada görünümünüz için ilişkili olay işleyicileri, 3. adımda ilan bağımlılık özelliğinden ICommand için devredeceğini :

    private void MyCustomCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e) { 
        var command = this.MyCustomCommand; 
        if (command != null) { 
         e.Handled = true; 
         e.CanExecute = command.CanExecute(e.Parameter); 
        } 
    } 
    private void MyCustomCommand_Executed(object sender, ExecutedRoutedEventArgs e) { 
        var command = this.MyCustomCommand; 
        if (command != null) { 
         e.Handled = true; 
         command.Execute(e.Parameter); 
        } 
    } 
    
  5. Son olarak, XAML özel bağımlılık özelliği (bir iCommand olmalıdır) sizin ViewModel komut uygulaması bağlamak:

    <local:MainView DataContext="{Binding MainViewModel}" 
           MyCustomCommand="{Binding CustomCommand}" /> 
    

Bu yaklaşımın avantajı, ViewModel'inizin yalnızca ICommand arabiriminin tek bir uygulamasını sağlaması gerektiğidir (ve hatta bir RelayCommand olabilir), ancak herhangi bir sayıda Görünüm, RoutedCommand aracılığıyla ona gerek duymadan doğrudan ViewModel'e bağlı.

Maalesef, ICommand.CanExecuteChanged olayının çalışmadığından bir dezavantajı var. ViewModel, View'in CanExecute özelliğini yenilemesini istediğinde, CommandManager.InvalidateRequerySuggested() öğesini çağırmanız gerekir.