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

CollectionViewSource updates and SelectedItem looses binding

7 Answers 382 Views
GridView
This is a migrated thread and some comments may be shown as answers.
jen
Top achievements
Rank 1
jen asked on 05 Jun 2017, 07:49 PM

I am using a radGridView in Master/Detail scenario using MVVM; the selected item is displayed in a custom form that allows editing.
The Form's DataContext and the Grid's SelectedItem are bound to a property in the ViewModel.
When the Grid's selection is changing, I check if the Form is in Edit mode, and if so I cancel the selection change.

This works as it should.

However, there are some circumstances where the Grid's ItemSource (CollectionViewSource) changes and the Grid looses track of the SelectedItem. I can throw NotifyPropertyChanged on the property, and the grid doesn't notice. When the grid is in this state and the user selects a row, the logic in SelectionChanging does not prevent the SelectedItem from changing. In fact it sets the SelectedItem to null, rather than the attempted selection row.

I really need to prevent the SelectedItem from changing (or becoming null) while the item is being edited. I think the best way would be to prevent the grid from getting into this strange state.

How can I force the grid to realize its SelectedItem, if NotifyPropertyChanged is not doing the trick?

Does the grid loose its SelectedItem binding when the Itemssource updates?

 

 

XAML:
    <telerik:RadGridView Grid.RowSpan="2" ShowGroupPanel="False" AutoGenerateColumns="False" IsFilteringAllowed="False"
        ItemsSource="{Binding Zones.View}"  x:Name="grd_ZoneBins" IsReadOnly="True" EditTriggers="None"
        SelectedItem="{Binding SelectedZone, Mode=TwoWay}"
        SelectionChanging="grd_ZoneBins_SelectionChanging" >
        <telerik:RadGridView.Columns>
            <telerik:GridViewDataColumn Header="Zone" DataMemberBinding="{Binding Name}" Width="*" />
            <telerik:GridViewDataColumn Header="Active" DataMemberBinding="{Binding IsActive}" />
        </telerik:RadGridView.Columns>
    </telerik:RadGridView>

CodeBehind:
    private void grd_ZoneBins_SelectionChanging(object sender, Telerik.Windows.Controls.SelectionChangingEventArgs e)
    {
        if (EditableWorkSpace_ZoneBins.Mode == EditMode.Editable) //this is a custom control
            e.Cancel = true;
    }

ViewModel:
    //Properties
    private List<Part_Zone> _zones;
    public CollectionViewSource Zones { get; set; }
    private Part_Zone m_SelectedZone;
    public Part_Zone SelectedZone
    {
        get { return m_SelectedZone; }
        set { m_SelectedZone = value; NotifyPropertyChanged("SelectedZone");}
    }

    public Model() //constructor
    {
        Zones = new CollectionViewSource();
        Zones.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending));
        LoadData();
    }

    private void LoadData()
    {
        _zones = GetZones();
        Zones.Source = _zones;
        SelectedZone = Zones.View.CurrentItem as Part_Zone; //first item
    }

    public void Refresh()
    {
        LoadData();
        //at this point the grid doesn't seem aware that the SelectedZone is its SelectedItem
    }

    public void StartEdit()
    {
        View.EditableWorkSpace_ZoneBins.Mode = EditMode.Editable;
        NotifyPropertyChanged("SelectedZone"); // just in case
    }

Steps to reproduce:
1) load data
2) select item in grid
3) refresh data - grid looses selectedItem. SelectedZone is not null.
4) start edit
5) change selection - gets canceled due to Edit mode
6) SelectedZone is set to null.


7 Answers, 1 is accepted

Sort by
0
jen
Top achievements
Rank 1
answered on 06 Jun 2017, 03:07 PM

Some additional information:
After the data gets refreshed, I show a MessageBox to tell the user the data has changed. The selected item changes to the first item in the list. The user clicks an edit button to start the edit, so the grid looses focus.

 

Sometimes the SelectedItem in the grid has a visible blue border around it and sometimes it doesn't (see image). When it doesn't have the border, and the user tries to change the selection but the selection Changing event is canceled, then the SelectedItem gets set to Null. This is the issue; it should be selecting the item it is bound to in the model, which is currently NOT null.

 

If the border is there then everything works correctly and the canceled SelectionChanging event sets the SelectedItem back to the right value.

I've attached an image to demonstrate

 

0
Stefan
Telerik team
answered on 08 Jun 2017, 02:11 PM
Hello Jen,

Thanks for the detailed explanation of the case.

Just for the test, can you please try reproducing this behavior with a source collection different from an ICollectionView? Is this behavior still replicated? Also, since the IsSynchronizedWithCurrentItem property of RadGridView is not set, it will have its default null value. This means, that when an ICollectionView is used as a source collection, the SelectedItem of RadGridView will be automatically synchronized with the CurrentItem. In the image provided, the border to which you refer is actually of the CurrentCell. So, can you please try setting the property to false? Is there any difference in the way the control behaves?

Regards,
Stefan X1
Progress Telerik
Want to extend the target reach of your WPF applications, leveraging iOS, Android, and UWP? Try UI for Xamarin, a suite of polished and feature-rich components for the Xamarin framework, which allow you to write beautiful native mobile apps using a single shared C# codebase.
0
jen
Top achievements
Rank 1
answered on 08 Jun 2017, 02:16 PM

Hello Stefan, 

Setting IsSynchronizedWithCurrentItem to false does not make any difference in this behaviour.

I will try a different data source and get back to you.

0
jen
Top achievements
Rank 1
answered on 08 Jun 2017, 06:33 PM

Hello Stefan, 

I just tried using a List as the ItemsSource. When the list gets updated, the grid automatically sets the SelectedItem to null. 
Since I want to keep my SelectedItem (and I know its still in the list), I put in some logic to prevent the value from changing, then threw a notifyPropertyChanged event on the SelectedZone property. I would expect the grid to acknowledge that event and re-select the row, but it is not. 

In this scenario, since the SelectedZone isn't null, I can begin the edit. Then when trying to select a row the grid cancels the selection changing event, but still sets the SelectedItem to null.

I even tried throwing the NotifyPropertyChanged event when the user clicks Edit, but the grid did not respond then either.

So the question remains; how do I make the grid become aware of the SelectedZone if the NotifyPropertyChanged event won't do the trick?

 

  private Part_Zone m_SelectedZone;

    public Part_Zone SelectedZone
    {
        get { return m_SelectedZone; }
        set {
             if (!IsUpdatingData)
                m_SelectedZone = value;
 
            NotifyPropertyChanged("SelectedZone");
        }
    }
    private void RefreshData()
    {
        //GetData();
        IsUpdatingData = true;
        NotifyPropertyChanged("_zones"); //the List Source

        NotifyPropertyChanged("SelectedZone");
        IsUpdatingData = false;
    }

0
Stefan
Telerik team
answered on 13 Jun 2017, 10:31 AM
Hello Jen,

Thanks for the update.

Unfortunately, based on it I am still not able to pinpoint the exact cause for the behavior you are experiencing. Can you please take a look at the project attached to my reply? As you should be able to see, on button click the source collection of RadGridView is reassigned and the property to which the SelectedItem of RadGridView is bound is updated. Am I missing something?

Also, in order to avoid any misunderstandings, may I kindly ask you to modify the sample application as per your setup and send it as an attachment through a new support ticket? We will be glad to assist you further.

Best Regards,
Stefan X1
Progress Telerik
Want to extend the target reach of your WPF applications, leveraging iOS, Android, and UWP? Try UI for Xamarin, a suite of polished and feature-rich components for the Xamarin framework, which allow you to write beautiful native mobile apps using a single shared C# codebase.
0
jen
Top achievements
Rank 1
answered on 13 Jun 2017, 04:46 PM

I have modified the project and opened a support ticket (1114166).

For anyone following: the issue is produced when the objects in the Item source stay the same instance when refreshed, as when using Entity DbContext. The selected item doesn't become a new instance, and is still the same instance as in the list. The grid refuses to acknowledge the propertyChanged event to set its selectedItem to the selected item

 

0
Stefan
Telerik team
answered on 16 Jun 2017, 09:02 AM
Hi Jen,

Thanks for the updated and for opening the support thread.

For the community, I will paste here your last reply from it, which happens to be the solution for this case.

It seems to me that I have to force the selectedItem to actually change its value, the notify event isn't enough. So I'm going to allow the grid to clear the selectedItem value, and then manually set it back. Rather than preventing it from changing in the first place. This seems to solve the issue.


Regards,
Stefan X1
Progress Telerik
Want to extend the target reach of your WPF applications, leveraging iOS, Android, and UWP? Try UI for Xamarin, a suite of polished and feature-rich components for the Xamarin framework, which allow you to write beautiful native mobile apps using a single shared C# codebase.
Tags
GridView
Asked by
jen
Top achievements
Rank 1
Answers by
jen
Top achievements
Rank 1
Stefan
Telerik team
Share this question
or