Search code examples
c#wpfbinding

how bind commands from listviewitem template


I have some templates in a ResourceDictionary like this one:

<DataTemplate x:Key="DefaultOrderItem" DataType="{x:Type m:OrderItem}">
    <Grid>
        <!-- Row/Column definition and other TextBoxes omitted -->

        <Button Grid.Row="0" Grid.Column="0" Name="DecCount" Padding="5,0,5,0"
                Command="{Binding OnDecCount}" CommandParameter="{Binding}">&lt;</Button>
        <TextBox Grid.Row="0" Grid.Column="1" Text="{Binding LabelCount, Mode=TwoWay}" FontSize="20"/>
        <Button Grid.Row="0" Grid.Column="2" Name="IncCount" Padding="5,0,5,0"
                Command="{Binding Path=OnIncCount}" CommandParameter="{Binding}">&gt;</Button>
        <Button Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="3" FontSize="20" Padding="5,0,5,0"
                Command="{Binding Path=DataContext.OnPrint}" CommandParameter="{Binding}"> Print </Button>

        <TextBox Grid.Row="0" Grid.Column="3" Grid.RowSpan="2" Text="{Binding PosNum}" VerticalAlignment="Center"
                 IsReadOnly="True" BorderThickness="0" FontSize="30" Background="Transparent"/>

        <TextBox Grid.Row="0" Grid.Column="10" Text="{Binding LabelType}" FontSize="20" VerticalAlignment="Center"/>
        <Button Grid.Row="1" Grid.Column="10" Name="Edit" Margin="3" FontSize="20" Padding="5,0,5,0"
                Command="{Binding OnEdit}" CommandParameter="{Binding}"> Edit </Button>
    </Grid>
</DataTemplate>

That template is used by an UserControl like this:

<ListView Grid.Row="1" Name="lstItems"
          AlternationCount="2"
          ItemsSource="{Binding OrderItems}"
          ItemContainerStyle="{StaticResource alternatingWithBinding}"
          ItemTemplateSelector="{StaticResource OrderItemTemplateSelector}"/>

I read a lot about command binding, but none of them works for me. As you can see, I tried different variants. I tried different command implementations too. I tried member of RelayCommand, functions in code behind of the view, functions in viewmodel and functions in model (OrderItem class), but none of it triggered.

So I hope, some can shine me a light.

Subsequent note (based on BionicCodes comment): I use Viewmodel first design, which means, I load a ViewModel and the corresponding View is loaded by dependencies written in xaml declarations.


Solution

  • The DataContext of the DataTemplate is always the templated data item, which is the OrderItem in your case. Unless OrderItem defines the commands like OnDecCount, your bindings won't resolve.

    You can use the Binding.RelativeSource proerty to traverse the element tree to find the proper DataContext.

    The following example binds the Button.Command property to the OnDecCount property that is found in the DataContext of the parent UserControl. The Button.CommandParameter is the clicked OrderItem:

    <DataTemplate x:Key="DefaultOrderItem" DataType="{x:Type m:OrderItem}">
      <Button Command="{Binding RelativeSource={RelativeSource AncestorType=UserControl}, Path=DataContext.OnDecCount}" 
              CommandParameter="{Binding}" />
    </DataTemplate>