Click here to Skip to main content
15,881,559 members
Articles / Desktop Programming / WPF

WPF/Silverlight ListBox and equality checking

Rate me:
Please Sign up or sign in to vote.
0.00/5 (No votes)
14 Feb 2011CPOL1 min read 11.6K   2
WPF/Silverlight ListBox and equality checking

In WPF, we bind collections of objects to ListBoxes and the like all the time – it's part and parcel of the WPF development cycle but this is something that stung me recently.

I bound a collection of objects to the ItemsSource property as usual but the selection was odd. Every time I selected an item, the ListBox assumed that the first item was also selected and subsequent selections marked all previous selections as selected, also the SelectedIndex was always 0. It took some time but I tracked it down to the way that ListBoxes use equality.

Something I didn’t know was that the objects that I was using had an overridden Equals method which was simply comparing a single string on the objects to determine if they were equal. Because I only wanted a small subset of the object, I only populated those properties I needed along with the id of the object and not the string being compared.

The below code shows an example of what I was doing.

C#
public class MainViewModel : INotifyPropertyChanged
{
    private ObservableCollection foos;

    public ObservableCollection Foos
    {
        get
        {
            return foos;
        }
        set
        {
            foos = value;
        }
    }

    public MainViewModel()
    {
        this.Foos = new ObservableCollection();
        this.Foos.Add(new Foo { id = 1, Display = "First" });
        this.Foos.Add(new Foo { id = 2, Display = "Second" });
        this.Foos.Add(new Foo { id = 3, Display = "Third" });
        this.Foos.Add(new Foo { id = 4, Display = "Fourth" });
        this.Foos.Add(new Foo { id = 5, Display = "Fifth" });
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

public class Foo
{
    public int id { get; set; }

    public string Display { get; set; }

    public string FooCode { get; set; }

    public override bool Equals(object obj)
    {
        return FooCode == (obj as Foo).FooCode;
    }
}

As we can see, I have no interest in the FooCode property and as a result don’t use it in my ViewModel.

The problem with this is that now the ListBox has no way of knowing if the objects are different as we have an overriding Equals method that implements value equality rather than reference equality and because the value is always going to be the same (as I don’t set it), then the ListBox will assume that every object is essentially the same object.

A simple change to include the FooCode property in each object in the collection solves this problem and gives us different values for equality testing.

A sample project with 2 lists displaying this different behaviour can be found here.


License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
United Kingdom United Kingdom
I am a developer currently working for a financial company in the UK with a focus on back end work using NServiceBus. Personally I also enjoy working with ASP.NET (MVC), WPF, ruby and investigating best practice using methods like TDD and bettering the quality of code.

Comments and Discussions

 
GeneralSimpler Pin
phil.o14-Feb-11 23:15
professionalphil.o14-Feb-11 23:15 
GeneralRe: Simpler Pin
Leom Burke14-Feb-11 23:21
Leom Burke14-Feb-11 23:21 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.