2010-08-14 8 views
7

Używam MVVM, a niestandardowe obiekty ICommand są dostarczane przez warstwę ViewModel. Jeden obiekt ViewModel w tym samym czasie można dołączyć za pośrednictwem właściwości DataContext do wielu obiektów View (okna, strony itp.). W ICommand.CanExecute() Chcę sprawdzić brak błędów sprawdzania poprawności dla niektórych formantów w widoku (które dołączone do rekwizytów ViewModel, istotne dla konkretnej komendy VM). Jeden ViewModel może dostarczyć wiele poleceń, każdy z nich ma własny zestaw kontrolek do sprawdzania poprawności błędów. Tak, pseudo-XAML jest:WPF: Jak przekazać całą kontrolę jako CommandParameter za pośrednictwem XAML?

<Button.CommandParameter> 
    <x:Array Type="sys_win:DependencyObject"> 
     <sys_win:DependencyObject> 
      <reference_to_textbox_or_other_control/> 
     </sys_win:DependencyObject> 
     <sys_win:DependencyObject> 
      <reference_to_textbox_or_other_control/> 
     </sys_win:DependencyObject> 
    </x:Array> 
</Button.CommandParameter> 

Drugim problemem jest to, że dana komenda może być wywołana przez kontrolę, która sama jest częścią DataTemplate dla elementu kolekcji (w moim przypadku - część ListBoxItem szablonu danych) . Mój szablonowy element listbox ma dwa pola tekstowe (powiązane z dwoma rekwizytami odpowiedniego ViewModelu) i przycisk, który wywołuje polecenie ViewModel. Tak więc, w poleceniu CanExecute() muszę sprawdzić błędy sprawdzania poprawności dla niektórych okien kontrolnych & dwa pola tekstowe, które należą do tego listitem, a nie inne elementy. Poniższy kod działa poprawnie, jeśli chcę przejść ListBoxItem.IsSelected nieruchomości jako CommandParameter:

<Button DataContext="{Binding}" 
     Command="{Binding Path=SwitchCommand}" 
     CommandParameter="{Binding Path=IsSelected, RelativeSource={ 
            RelativeSource 
            Mode=FindAncestor, 
            AncestorType={x:Type ListBoxItem}}}"/> 

Ale jak mogę przekazać całość (DependencyObject) ListBoxItem jak CommandParameter? I w jaki sposób ten ListBoxItem, przekazywany za pośrednictwem {Binding RelativeSource} może być mieszany z innymi bieżącymi kontrolkami okna w pierwszym przykładzie kodu?


Bardzo mi przykro, ale jak dodać odniesienia do elementów sterujących w Xaml?

<Button.CommandParameter> 
    <x:Array Type="sys_win:DependencyObject"> 
     <sys_win:DependencyObject> 
      <reference_to_textbox_or_other_control/> 
     </sys_win:DependencyObject> 
     <sys_win:DependencyObject> 
      <reference_to_textbox_or_other_control/> 
     </sys_win:DependencyObject> 
    </x:Array> 
</Button.CommandParameter> 
+0

StackOverflow nie jest forum; jeśli chcesz dodać więcej szczegółów, [edytuj swoje pytanie] (http://stackoverflow.com/posts/3482343/edit). Odpowiedzi mają być odpowiedziami, a nie dodatkowymi informacjami na temat pytania. – Will

Odpowiedz

23

Wystarczy użyć wiążąca bez Path:

<Button DataContext="{Binding}" 
     Command="{Binding Path=SwitchCommand}" 
     CommandParameter="{Binding RelativeSource= 
            {RelativeSource 
            Mode=FindAncestor, 
            AncestorType={x:Type ListBoxItem}}}"/> 
+0

Thomas Levesque, dziękuję. Działa, :) –

1

Nie jestem pewien, czy mam poprawnie czyta swój przykład, ale wydaje się naruszać trochę zasady MVVM. (Przepraszam, jeśli przeczytałem to niepoprawnie).

Ideą MVVM jest oderwanie modelu widoku od dowolnej zależności od obiektu XAML/View. Łamiesz to, uzależniając CommandParameter od kontroli użytkownika. Chciałbym stworzyć właściwości stanu w ViewModelu i powiązać walidacje usercontrol z tymi stanami, a następnie w CanExecute można przetestować wartości tych właściwości, zamiast próbować powiązać z kontrolką użytkownika.

+0

Doobi, angielski nie jest moim ojczystym językiem, znałem go raczej źle niż normalnie, więc twoje niepełne zrozumienie pierwszego wpisu to moja wina, :) ViewModel dostarcza poleceń, które wykorzystują właściwości również dostarczane przez ViewModel. Właściwości zostały powiązane z Sprawdzaniem kontroli i błędów dostarczonymi przez IDataErrorInfo, którego implementacja jest również częścią ViewModel. Pomimo faktu, że w polu Wyświetl wszystkie wartości błędów oznaczone specjalnym szablonem, użytkownik może spróbować wywołać jedno z poleceń programu ViewModel, który korzysta z właściwości z (aktualnie) wartościami błędu. Aby zablokować tę zdolność, mamy do czynienia z ICo –

+0

ICommand.Execute() sprawdza wszystkie właściwości, których wartości są używane przez to polecenie. Tak więc sprawdzamy właściwości ViewModel dla błędów dwa razy: 1) w ciągu znaków IDataErrorInfo.this [nazwa właściwości łańcucha] po zmianie wartości właściwości 2) w ICommand.CanExecute, gdy aktualizacja silnika WPF UI Aby uniknąć implementacji (2) Chcę przesłać listę formantów widoku (związanych z właściwościami ViewModel, które są znaczące dla bieżącego polecenia ViewModel) w ICommand.CanExecute jako CommandParameter i sprawdzić błędy za pośrednictwem Validation.GetHasError (DependencyObject). –

+0

Ponieważ polecenie pobiera listę DependencyObjects, ViewModel pozostaje niezależny od widoku. Ale dziś po wielu myślach doszedłem do wniosku, że moje podejście jest jak wynalezienie kwadratowego koła i odmówiłem tego pomysłu. –

Powiązane problemy