Home > Software design >  How to bind properties from DataContext while Itemssource is binding?
How to bind properties from DataContext while Itemssource is binding?

Time:09-17

I want to bind a RadioButton with a property in a view model,but it seems to be binding with ItemSource now. I still need ItemsSource to get my DataGrid view items, so how can I fix it?

<DataGrid DataContext="{Binding ViewModels[0]}" ItemsSource="{Binding LimitItems}">
    <DataGrid.Columns>
        <DataGridTemplateColumn Width="55" Header="Select">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <!--radiobutton binding from datacontext-->
                    <RadioButton Checked="{Binding SetLimitCommand}" GroupName="Setting" />
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
        <DataGridTextColumn
            Width="120"
            Binding="{Binding MeasItem}"
            Header="MeasureItem" />
    </DataGrid.Columns>
</DataGrid>

CodePudding user response:

First of all, Checked is an event. You can add an event handler defined in code-behind to it, but you cannot bind it, it will throw an exception at runtime.

InvalidCastException: Unable to cast object of type System.Reflection.RuntimeEventInfo to type System.Reflection.MethodInfo.

You can instead bind the Command property of the RadioButton. The data context of the each cell in the template column will be set to the current item for the row in the ItemsSource. This means that you have to use a RelativeSource binding in order to refer to the DataContext of the DataGrid.

<RadioButton Command="{Binding DataContext.SetLimitCommand, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" GroupName="Setting" />

If you really need to bind a command to an event, you could use the Microsoft.Xaml.Behaviors.Wpf NuGet package (which is a replacement for System.Windows.Interactivity) like this.

<RadioButton GroupName="Setting">
   <b:Interaction.Triggers>
      <b:EventTrigger EventName="Checked">
         <b:InvokeCommandAction Command="{Binding DataContext.SetLimitCommand, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"/>
      </b:EventTrigger>
   </b:Interaction.Triggers>
</RadioButton>

CodePudding user response:

When you bind the ItemsSource Property, all subsequent Bindings refer to the current Item's Properties. So in this case the Property SetLimitCommand is expected to be part of your Item-Type. To bind the command to the ViewModel you could use RelativeSource-Binding

<RadioButton Checked="{Binding RelativeSource={RelativeSource AncestorType=DataGrid}, Path=DataContext.SetLimitCommand}" GroupName="Setting" />

Anyway, I never tried to bind a Command to an Event... I'd prefer to bind to the Command Property, then you can pass the current item as CommandParameter too.

  • Related