Search code examples
wpfmvvm-lightmultibinding

How to use multibinding on a rectangle-command in mvvm?


I got the following rectangle

<Rectangle
    Width="{Binding Width}"
    Height="{Binding Length}"
    Tag="{Binding Id}"
    Name="rectangleDrawnMachine">

    <i:Interaction.Triggers>
        <i:EventTrigger
            EventName="MouseDown">
            <cmd:EventToCommand
                Command="{Binding Main.UpdateSelectedMachine, Mode=OneWay, Source={StaticResource Locator}}"
                PassEventArgsToCommand="True"
                CommandParameter="{Binding ElementName=rectangleDrawnMachine}" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
</Rectangle>

The rectangle is bound to a model which is declared in an above ItemsControl. The document-structure is like the following:

<Grid>
    <ItemsControl ItemsSource="{Binding AllMachines}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <Canvas Name="canvasDrawnMachines" />
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>

        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Grid>
                    <Rectangle Name="rectangleDrawnMachine"/>
                </Grid>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Grid>

Now my UpdateSelectedMachine-command needs at least three properties of the rectangle:

  • Position x
  • Position y
  • ID / Tag

With the CommandParameter of the rectangle itself my command will get a lot of informations about the rectangle (like the neccessary tag). But it doesnt get the neccessary information about the (X- & Y-)position of the canvas.

So my question is: how to use multibinding on my rectangle-command? And how to transfer the positions of the canvas?


Solution

  • You cannot pass multiple values by using command parameter.

    In order to do so, you have to use multi binding.

    <cmd:EventToCommand
                Command="{Binding Main.UpdateSelectedMachine, Mode=OneWay, Source={StaticResource Locator}}"
                PassEventArgsToCommand="True">
    <cmd:EventToCommand.CommandParameter>
     <MultiBinding Converter="{StaticResource YourConverter}">
                     <Binding Path="Canvas.Left" ElementName="canvasDrawnMachines"/>
                     <Binding Path="Canvas.Top" ElementName="canvasDrawnMachines"/>
                     <Binding Path="Tag" ElementName="canvasDrawnMachines"/>
     </MultiBinding>
    </cmd:EventToCommand.CommandParameter>
    

    Your converter:

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

    Then, execution command logic:

    public void OnExecute(object parameter)
    {
        var values = (object[])parameter;
        var left = (double)values[0];
        var top = (double)values[1];
        var tag = values[2]; 
    }