[wpf] WPF 바인딩을 사용하여 두 개의 명령 매개 변수 전달

다음 표준 구문을 사용하여 XAML 파일에서 실행중인 명령이 있습니다.

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

이것은 사용자가 기대하는 방식 (캔버스의 너비와 높이)을 완료하기 위해 뷰에서 두 가지 정보가 필요하다는 것을 알기 전까지는 잘 작동했습니다.

배열을 내 명령에 인수로 전달하는 것이 가능한 것처럼 보이지만 CommandParameter에서 두 개의 캔버스 속성에 대한 바인딩을 지정하는 방법이 없습니다.

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

너비와 높이를 모두 명령에 어떻게 전달합니까? XAML의 명령을 사용하여 이것이 가능하지 않은 것으로 보이며이 정보를 내 확대 방법으로 전달하려면 코드 숨김에 클릭 처리기를 연결해야합니다.



답변

첫째, MVVM을 수행하는 경우 일반적으로 뷰에서 바인딩 된 별도의 속성을 통해 VM에서이 정보를 사용할 수 있습니다. 따라서 모든 매개 변수를 명령에 전달하지 않아도됩니다.

그러나 멀티 바인딩하고 변환기를 사용하여 매개 변수를 작성할 수도 있습니다.

<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>

변환기에서 :

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

    ...
}

그런 다음 명령 실행 논리에서 :

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


답변

선택한 솔루션의 변환기에서 값을 추가해야합니다. 그렇지 않으면 명령의 매개 변수가 널을 종료합니다.

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

    ...
}


답변

변환기에서 Tuple을 사용하고 OnExecute에서 매개 변수 오브젝트를 다시 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;
}


답변

값이 정적이면 다음을 사용할 수 있습니다 x:Array.

<Button Command="{Binding MyCommand}">10
  <Button.CommandParameter>
    <x:Array Type="system:Object">
       <system:String>Y</system:String>
       <system:Double>10</system:Double>
    </x:Array>
  </Button.CommandParameter>
</Button>


답변

변환기에서 Tuple을 사용하는 경우 ‘string’개체를 제한하지 않고 모든 유형의 개체에 대해 작동하도록 ‘string’대신 ‘object’를 사용하는 것이 좋습니다.

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

그런 다음 Command의 실행 로직은 다음과 같습니다.

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;
}

매개 변수를 만들기 위해 변환기를 사용하여 멀티 바인딩합니다 (두 개의 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>


답변