Search code examples
wpfwpfdatagrid

How to bind a single property to the selection of two Controls in WPF?


I have two DataGrids filled with separate collections of objects of the same type. In my ViewModel I have one property "CurrentObject" that I want to bind to the currently selected object.

That means that if I select a row in DataGrid A the CurrentObject holds the selected Item of DataGrid A and the if i select a row in DataGrid B the CurrentObject holds the selected Item of DataGrid B.

In both DataGrids I've done the binding like this:

<DataGrid SelectedItem="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.CurrentObject}">

It only works as expected when I change the selection within one DataGrid. If I select a already selected row the CurrentObject property isn't updated and still references to the object from the other DataGrid. I guess it's because the SelectionChanged event isn't fired then


Solution

  • Rang also had the idea to use Interaction Triggers to avoid code behind. Looks like we had the same idea at the same time. His approach is to handle the LostFocus event in an extra view models method, mine is to handle the GotFocus with binding. I think it's a personally preference which way to go. For the sake of completeness:

    <iy:Interaction.Triggers>
        <iy:EventTrigger EventName="GotFocus">
            <is:ChangePropertyAction TargetObject="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext}" 
                                     PropertyName="CurrentObject" 
                                     Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}, Path=SelectedValue}" />
        </iy:EventTrigger>
    </iy:Interaction.Triggers>
    

    Since the Binding is only updated when the selection is changed within a single control, I additionally change the property when the DataGrid got the focus