2009-08-29 13 views
122

Mam polecenia, które ja wykonywanie od mojego pliku XAML stosując następującą standardową składnię:Przechodząc dwa parametry polecenia przy użyciu WPF wiążących

<Button Content="Zoom" Command="{Binding MyViewModel.ZoomCommand}"/> 

To działało w porządku, aż zdałem sobie sprawę, że muszę dwie informacje od widoku w celu wykonania tej operacji w sposób zgodny z oczekiwaniami użytkowników (szerokość i wysokość płótna).

Wydaje się, że to możliwe, aby przekazać tablicę jako argument do mojego polecenia, ale nie widzę tam będąc sposób określić wiązanie do moich dwóch właściwości płótnie w CommandParameter:

<Button Content="Zoom" 
     Command="{Binding MyViewModel.ZoomCommand" 
     CommandParameter={Binding ElementName=MyCanvas, Path=Width}"/> 

Jak przekazać zarówno szerokość, jak i wysokość do mojego polecenia? Wydaje się, że nie jest to możliwe za pomocą poleceń z XAML i muszę podłączyć obsługę kliknięcia w moim kodzie, aby przekazać tę informację do mojej metody powiększania.

Odpowiedz

182

Po pierwsze, jeśli robisz MVVM, zazwyczaj masz tę informację do swojej maszyny wirtualnej poprzez oddzielne właściwości związane z widokiem. To oszczędza konieczności przekazywania jakichkolwiek parametrów do poleceń.

Jednakże, można również wiele powiązań i używać konwertera, aby utworzyć parametry:

<Button Content="Zoom" Command="{Binding MyViewModel.ZoomCommand"> 
    <Button.CommandParameter> 
     <MultiBinding Converter="{StaticResource YourConverter}"> 
      <Binding Path="Width" ElementName="MyCanvas"/> 
      <Binding Path="Height" ElementName="MyCanvas"/> 
     </MultiBinding> 
    </Button.CommandParameter> 
</Button> 

w twojej Przelicznik:

public class YourConverter : IMultiValueConverter 
{ 
    public object Convert(object[] values, ...) 
    { 
     return values.Clone(); 
    } 

    ... 
} 

Następnie w realizacji logiki polecenia:

public void OnExecute(object parameter) 
{ 
    var values = (object[])parameter; 
    var width = (double)values[0]; 
    var height = (double)values[1]; 
} 
+1

Dzięki Kent - To było dokładnie to, czego szukałem. Najbardziej podoba mi się twoje pierwsze podejście, aby VM znała "stan" widoku poprzez wiązanie bez konieczności przekazywania parametrów, ale wciąż mogę go przetestować. Nie jestem pewien, czy będzie to działało dla mnie tutaj, ponieważ potrzebuję widoku, aby płótno było jak największe i przekazałem tę wartość do VM. Jeśli go zwiążę, czy nie będę musiał ustawić szerokości w VM? W takim przypadku maszyna wirtualna jest związana z widokiem? – JasonD

+0

@Jason: możesz to zrobić w dowolny sposób. Oznacza to, że widok powoduje przejście z powrotem do modelu widoku lub model widoku przesuwa zmiany do widoku. Wiązanie TwoWay spowoduje, że którakolwiek opcja będzie dostępna. –

+0

w moim programie parametr metody OnExecute jest tablicą z wartościami zerowymi, ale w konwerterze wartości są zgodne z oczekiwaniami. –

13

Użyj Tuple w konwerterze, aw OnExecute przenieś obiekt parametru z powrotem do Tuple.

public class YourConverter : IMultiValueConverter 
{  
    public object Convert(object[] values, ...)  
    { 
     Tuple<string, string> tuple = new Tuple<string, string>(
      (string)values[0], (string)values[1]); 
     return (object)tuple; 
    }  
} 

// ... 

public void OnExecute(object parameter) 
{ 
    var param = (Tuple<string, string>) parameter; 
} 
35

w konwerterze od wybranego rozwiązania, należy dodać values.Clone() inaczej parametry w końcu polecenia zerowej

public class YourConverter : IMultiValueConverter 
{ 
    public object Convert(object[] values, ...) 
    { 
     return values.Clone(); 
    } 

    ... 
} 
+2

Witam, ten dodatek z Clone() sprawia, że ​​to działa :) Czy możesz wyjaśnić, jaka to robi różnica. Becuase Nie rozumiem, dlaczego potrzebuje tego Clone() do pracy? Dziękuję Ci. – adminSoftDK

Powiązane problemy