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

SelectedItem and equality

5 Answers 47 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Dmitry
Top achievements
Rank 1
Dmitry asked on 29 Oct 2012, 11:22 AM
Hi everyone.

We've recently moved to SL5 and the latest version of SL controls (2012.3.1017.1050). We were totally surprised some of our code fails to work properly. One of the issues is about grid view selection. I prepared a little demo code which illustrates it. We have a grid:

<telerik:RadGridView AutoGenerateColumns="false" ItemsSource="{Binding DummyObjects}"
            Width="600" IsSynchronizedWithCurrentItem="false"
            SelectedItem="{Binding SelectedItem, Mode=TwoWay}">
            <telerik:RadGridView.Columns>
                <telerik:GridViewSelectColumn />   
                <telerik:GridViewDataColumn DataMemberBinding="{Binding Id}" />
                <telerik:GridViewDataColumn DataMemberBinding="{Binding Name}" />
            </telerik:RadGridView.Columns>           
        </telerik:RadGridView>

In view model there is a property DummyObjects which is ObservableCollection<DummyObject>. Property is populated in the constructor with 10 objects with ids ranging from 1 to 10.

DummyObject class:

public class DummyObject
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
 
        protected bool Equals(DummyObject other)
        {
            return Id == other.Id;
        }
 
        public override bool Equals(object obj)
        {
            if (ReferenceEquals(null, obj)) return false;
            if (ReferenceEquals(this, obj)) return true;
            if (obj.GetType() != this.GetType()) return false;
            return Equals((DummyObject) obj);
        }
 
        public override int GetHashCode()
        {
            return Id;
        }
    }

At the end of the view model constructor I have the following:

SelectedItem = new DummyObject() { Id = 2 };

SelectedItem is a view model property as well.

I expected selection of the second row which actually worked in SL4, 2011 Q3. But now selection doesn't happen. Interestingly, grid's SelectedItem and SelectedItems are populated with my object but checkbox is not checked.

Making selected item be one of items in source collection does the selection:

SelectedItem = DummyObjects[1];
 
So my question: did something changed in SL5 or gridview behavior causing not working custom equality comparison for selected items? It seems like now it's ignored, only reference comparison is performed. 

I made the same research with SL Toolkit datagrid and selection works.

5 Answers, 1 is accepted

Sort by
0
Vera
Telerik team
answered on 29 Oct 2012, 01:46 PM
Hello Dmitry,

We would strongly advice you not to override Equals and GetHashCode methods since RadGridView uses the hash code of the items in the selection logic. In order to achieve the desired behavior, please use the second approach for setting the SelectedItem property.  

Greetings,
Vera
the Telerik team

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

0
Dmitry
Top achievements
Rank 1
answered on 29 Oct 2012, 03:09 PM
Vera, thank you for the reply. But the example shows that grid view is likely not using gethashcode and equals for selection logic at all. I want selection be based on Id property and overriding equality members was a common approach.

Additional checks for selected items to be a subset of objects from ItemsSource cause many changes in code in scenarios like refreshing source collection, etc.

Btw, if this behavior changed, could you point me to some release notes or something to understand when and why this happened?

Thanks in advance.
0
Vera
Telerik team
answered on 29 Oct 2012, 04:23 PM
Hello Dmitry,

 

Internally we store a dictionary of all selected items. If two items have the same hash code and their Equals method dictates that they are, indeed, the same we will also consider them as one and the same object. In such situations the selection mechanism might not work very well.  

As for your particular logic, I have tested the code you have provided with the mentioned version (Q3 2011), but I did not observed the described behavior and no item was selected. Will it be possible to open a support ticket and to send a simple runnable project demonstrating the approach you use so we can test it on our side? 


Greetings,
Vera
the Telerik team

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

0
Dmitry
Top achievements
Rank 1
answered on 30 Oct 2012, 11:16 AM
Yes, Vera, you are right. Q3 2011 has the same behavior. The difference is if a selected item is not in the source collection then grid's SelectedItem becomes null and object is removed from SelectedItems collection. SL 5 Q3 2012 preserves SelectedItem and SelectedItems even if this object is not found in source collection. Could you explain why so?

SL Toolkit data grid has different behavior in my example. It internally finds selected object in source collection and updates its SelectedItem with it.

BTW, could you point me then how and what for equality members are used in selection?
0
Maya
Telerik team
answered on 02 Nov 2012, 09:27 AM
Hello Dmitry,

When RadGridView is loaded, the initialization of the SelectedItem is validated firstly through:

private static object ItemCoerce(DependencyObject d, object baseValue)
        {
            var dataControl = (DataControl) d;
            int itemIndex = -1;
 
            if (baseValue == null)
                return baseValue;
 
            if (dataControl.Items != null)
                itemIndex = dataControl.Items.IndexOf(baseValue);
 
            if (itemIndex >= 0)
                return baseValue;
            else
                return UnsetValue;
        }

When the item is not in the source, it returns (-1), thus setting the value to  "UnsetValue". That is why my recommendation would be to get the selected item from the source collection. For example:
public MyViewModel()
        {
            this.SelectedItem = this.DummyObjects.Where(d => d.Id == 2).FirstOrDefault();          
        }

Considering overriding GetHashCode and Equals methods,  if two items have the same hash code and their Equals method returns true, the grid is not able to say that those items are different. Thus the SelectedItems collection might not contain the results you want and you can end up with some undesired behavior. You need to make sure that all those methods will be unique for each item (return unique hash code). That is why we suggest not to override them as you might get undesirable results. 

Kind regards,
Maya
the Telerik team

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

Tags
GridView
Asked by
Dmitry
Top achievements
Rank 1
Answers by
Vera
Telerik team
Dmitry
Top achievements
Rank 1
Maya
Telerik team
Share this question
or