Przekazywanie dwóch parametrów poleceń za pomocą wiązania WPF

Mam polecenie, które wykonuję z mojego pliku XAML, używając standardowej składni:

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

Działało to dobrze, dopóki nie zdałem sobie sprawy, że potrzebuję dwóch informacji z widoku, aby ta operacja zakończyła się tak, jak oczekują użytkownicy(szerokość i wysokość płótna).

Wydaje się, że możliwe jest przekazanie tablicy jako argumentu do mojego polecenia, ale nie widzę sposobu, aby określić powiązanie z moimi dwoma właściwościami canvas w CommandParameter:

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

Jak przekazać szerokość i wysokość mojej komendzie? Wydaje się, że nie jest to możliwe przy użyciu poleceń z XAML i muszę podłączyć obsługę kliknięć w moim kodzie, aby uzyskać te informacje, aby przekazać je do mojej metody zoom.

Author: Kjartan, 2009-08-29

4 answers

Po pierwsze, jeśli wykonujesz MVVM, zazwyczaj masz te informacje dostępne dla maszyny Wirtualnej za pomocą oddzielnych właściwości powiązanych z widokiem. Dzięki temu nie musisz w ogóle przekazywać żadnych parametrów do poleceń.

Można jednak również multi-bind i użyć konwertera do utworzenia parametrów:

<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 Twoim konwerterze:

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

    ...
}

Następnie w logice wykonania polecenia:

public void OnExecute(object parameter)
{
    var values = (object[])parameter;
    var width = (double)values[0];
    var height = (double)values[1];
}
 195
Author: Kent Boogaart,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-07 20:08:58

W konwerterze wybranego rozwiązania należy dodać wartości.Clone() w przeciwnym razie parametry w Komendzie end null

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

    ...
}
 36
Author: Daniel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-21 08:36:15

Użyj krotki w konwerterze, a w OnExecute przenieś obiekt parametru z powrotem do krotki.

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;
}
 13
Author: Melinda,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-18 22:12:07

Jeśli chodzi o użycie krotki w konwerterze, lepiej byłoby użyć 'object' zamiast 'string' , tak aby działał on dla wszystkich typów obiektów bez ograniczeń obiektu 'string'.

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

Wtedy logika wykonania polecenia może wyglądać tak

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

    // e.g. for two TextBox object
    var txtZip = (System.Windows.Controls.TextBox)param.Item1;
    var txtCity = (System.Windows.Controls.TextBox)param.Item2;
}

I multi-bind z konwerterem do tworzenia parametrów (z dwoma obiektami TextBox)

<Button Content="Zip/City paste" Command="{Binding PasteClick}" >
    <Button.CommandParameter>
        <MultiBinding Converter="{StaticResource YourConvert}">
            <Binding ElementName="txtZip"/>
            <Binding ElementName="txtCity"/>
        </MultiBinding>
    </Button.CommandParameter>
</Button>
 0
Author: alex,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-15 11:26:46