Thursday, October 29, 2009

XAML Combobox SelectedItem binding

Combobox SelectedItem binding in XAML  did not work for me at first.

This is the XAML for binding:

<ComboBox x:Name="format" DisplayMemberPath="Text" SelectedItem="{Binding Format}" IsEditable="False"   />

This is the code behind:

PublishingFormatRepository pf = new PublishingFormatRepository(Current.BookshelfPath);
List<PublishingFormat> publishingFormats = pf.All as List<PublishingFormat>;
format.ItemsSource = publishingFormats;
if (publishingFormats != null) format.SelectedItem = publishingFormats[0];

set
{
_book = value;
DataContext = _book;
}

It’s simple, it should work. I attached a binding tracer to the binding extension but there was no problem. After a while something came on my mind: object equality. I checked something like this:

_book.Format == publishingFormats[0]

It should have been true but it was false.

So the solution is simple:

[Serializable]
public class PublishingFormat : IEquatable<PublishingFormat>
{
////////////////
// Members here
////////////////

public override bool Equals(object obj)
{
return Equals(obj as PublishingFormat);
}

#region IEquatable<PublishingFormat> Members

public virtual bool Equals(PublishingFormat other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return other.Id.Equals(Id);
}

#endregion

public override int GetHashCode()
{
return Id.GetHashCode();
}

public static bool operator ==(PublishingFormat left, PublishingFormat right)
{
return Equals(left, right);
}

public static bool operator !=(PublishingFormat left, PublishingFormat right)
{
return !Equals(left, right);
}
}

The class implements the IEquatable interface and overrides the Equals function and the ==, != operators. In my case the equality will be evaluated by comparing the Id fields of the classes.

Now the simple XAML expression above works.

Link: How to: Define Value Equality for a Type (C# Programming Guide) [MSDN]