This is a migrated thread and some comments may be shown as answers.

Trying to keep the SelectedItem property in two RadGridView controls in synch

2 Answers 33 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Tony
Top achievements
Rank 1
Tony asked on 30 Mar 2012, 07:26 PM
My app is a WPF application designed for use on a touch screen equipped laptop mounted in police cars.  Every control is larger in size and uses a larger font, just to make the application easy to read while driving and easy to interact with.

My main window has a RadTabControl in it.  In one tab I have a Search control I built.  This has a bunch of criteria fields at the top and a RadGridView on the bottom that displays all the rows returned from the datbase that matches the user's criteria.  This is fine and dandy.  Let's call this the Searcher control.

On another tab, I have a new control that I'm building.  This control contains a third party mapping control in it.  All of the data in the database is stamped with geographical coordinates and this new control needs to map each row returned on the map.  Let's call this the Map control.

To make this happen, the Searcher control contains a DependencyProperty called Reads.  This is an ObservableCollection of view model objects corresponding to the data returned by the search.  The Map control also has a DependencyProperty called Reads of the same type.  In the Xaml for my window, I bind the Map control's Reads property to the Searcher Control's Reads property using xaml like this:

<telerik:RadTabControl Name="OperationsTabs"
                SelectionChanged="Tabs_SelectionChanged"
                Visibility="Collapsed">
   
    <telerik:RadTabItem Header="  Search  "
                Name="SearchTab">
        <cs:Searcher Name="SearchControl" />
    </telerik:RadTabItem>
  
    <telerik:RadTabItem Header="Map Results"
                Name="MapResultsTab">
        <cs:MapResults Name="MapResults"
                 Reads="{Binding ElementName=SearchControl, Path=Reads}" />
    </telerik:RadTabItem>
</telerik:RadTabControl>

Here is some code that gets run when the value of the Reads DependencyProperty in the Map control changes:

public void OnReadsChanged( ObservableCollection<ReadViewModel> newValue ) {
    ReadsGrid.ItemsSource = newValue;
}
  
public static void OnReadsChanged( DependencyObject d, DependencyPropertyChangedEventArgs e ) {
    MapResults map = (MapResults) d;
    map.OnReadsChanged( (ObservableCollection<ReadViewModel>) e.NewValue );
}

I have seen the code in these methods run in the debugger, so I know that the assignment occurs.

I have added a SelectionChanged event handler to the RadGridView on the Searcher control. Here is what that event does:

private void ReadsGrid_SelectionChanged( object sender, SelectionChangeEventArgs e ) {
    if ( ProcessChange ) {
        MapResultsControl.ProcessChange = false;
        MapResultsControl.ReadsGrid.SelectedItem = ReadsGrid.SelectedItem as ReadViewModel;
        MapResultsControl.ProcessChange = true;
    }
    e.Handled = true;
}

I have also added a SelectionChanged event handler to the RadGridView on the Map control  Here is what that event does:

private void ReadsGrid_SelectionChanged( object sender, Telerik.Windows.Controls.SelectionChangeEventArgs e ) {
    if ( ProcessChange ) {
        SearchControl.ProcessChange = false;
        SearchControl.ReadsGrid.SelectedItem = ReadsGrid.SelectedItem;
        SearchControl.ProcessChange = true;
    }
}

There is code in the MainWindow which assigns the appropriate object references to the MapResultsControl and SearchControl properties.

The idea behind this code is to make sure that the selected item in both RadGridViews stay in synch.  If you change it in one, it changes it in the other.  The ProcessChange flags are there to prevent an infinite recursion of one calling the other.

Now, this works, provided the Map control has been rendered before you try selecting a row in either control.  If you switch to the Map Results tab after finishing the search, the RadGridView is populated with data.  Then selecting a row in either control changes the SelectedItem in the other.

BUT if you select a row in the Searcher control's RadGridView BEFORE you display the Map Results tab, nothing gets selected in the other RadGridView.  This is because the Items property is empty if the RadGridView hasn't been rendered.  I know it is because I've stepped through the code in the debugger and I checked.

So how do I fix this?  What's a good work around for this scenario?

Tony

2 Answers, 1 is accepted

Sort by
0
Accepted
Pavel Pavlov
Telerik team
answered on 02 Apr 2012, 02:11 PM
Hello Tony,

The technique of listening to events of two or more controls is considered a bit unrelieable ( as you have discovered) .  A better way would be to use an items source collection which knows about the current item e.g.
a CollectionViewSource. RadGridView would respect the current item in the source collection. I believe your other control would also do .

An alternative solution may also be found at this blog post : http://blogs.telerik.com/blogs/posts/10-05-31/how-to-synchronize-your-ui-selected-items-with-your-data-context-using-mvvm-and-blend-behaviors-for-silverlight-and-wpf.aspx

Regards,
Pavel Pavlov
the Telerik team
Sharpen your .NET Ninja skills! Attend Q1 webinar week and get a chance to win a license! Book your seat now >>
0
Tony
Top achievements
Rank 1
answered on 03 Apr 2012, 08:27 PM
Pavel:

Thank you!  I am now using a CollectionViewSource and it's working wonderfully!  It's exactly what I needed.

Tony
Tags
GridView
Asked by
Tony
Top achievements
Rank 1
Answers by
Pavel Pavlov
Telerik team
Tony
Top achievements
Rank 1
Share this question
or