While working on combo box I found out a wired issue. Xaml looks like this
<ComboBox x:Name="cb" ItemsSource="{Binding MyEntity.Choices}"
SelectedItem="{Binding MyEntity.Choice,Mode=TwoWay}"
Height="25"
HorizontalAlignment="Stretch"
VerticalAlignment="Top"/>
Let’s say Itemsource is binded with a List of Shaft (object) & selectedItem is one among the list.
public partial class MainWindow : Window
{
private ShaftsData shaftData;
public ShaftsData ShaftData
{
get { return shaftData; }
set { shaftData = value; }
}
public MainWindow()
{
ShaftData = new ShaftsData();
InitializeComponent();
txtBox.Text = "Default";
this.DataContext = this;
SetComboCollectionAndSelectedShaft();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
shaftData.ComboCollection = null;
}
private void SetComboCollectionAndSelectedShaft()
{
Collection<Shaft> myCollection = new Collection<Shaft>();
for (int i = 1; i <= 5; ++i)
{
Shaft sh = new Shaft();
sh.Id = i;
sh.Name = string.Format("{0} {1} ", txtBox.Text, i);
myCollection.Add(sh);
}
shaftData.ComboCollection = myCollection;
shaftData.SelectedShaft = shaftData.ComboCollection[0];
}
}
public class ShaftsData : INotifyPropertyChanged
{
private Collection<Shaft> _comboCollection;
private Shaft _selectedShaft;
public Collection<Shaft> ComboCollection
{
get
{
return _comboCollection;
}
set
{
_comboCollection = value;
OnPropertyChanged("ComboCollection");
}
}
public Shaft SelectedShaft
{
get { return _selectedShaft; }
set
{
_selectedShaft = value;
OnPropertyChanged("SelectedShaft");
}
}
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
}
And then I tried to make this list to null (Please refer to Button_Click) .Combobox is calling the .Equals of each object of the List & compare the last Selected object. While my expectation is it should not call .equals & set the SelectedItem to null.
public class Shaft
{
private int _id;
private string _name;
public int Id {
get { return _id; }
set {
_id = value;
}
}
public string Name
{
get { return _name; }
set
{
_name = value;
}
}
public override string ToString()
{
return _name;
}
public override bool Equals(object obj)
{
System.Diagnostics.Debug.WriteLine("Calling from object.Equals");
Shaft shaft = obj as Shaft;
if (null != shaft)
{
System.Diagnostics.Debug.WriteLine("Equals called for " + this.Name + ". Compared with " + shaft.Name);
}
else
{
System.Diagnostics.Debug.WriteLine("Equals called for " + this + ". Compared with " + shaft);
}
return base.Equals(obj);
}
Now if I implement IEquatable on Shaft & then set the List to null it works fine. Means no call is going to .Eqauls & selectedItem is set to null.
New Implementation
public class Shaft : IEquatable<Shaft>
{
private int _id;
private string _name;
public int Id {
get { return _id; }
set {
_id = value;
}
}
public string Name
{
get { return _name; }
set
{
_name = value;
}
}
public override string ToString()
{
return _name;
}
public bool Equals(Shaft shaft)
{
System.Diagnostics.Debug.WriteLine("Calling from object.Equals");
// Shaft shaft = obj as Shaft;
if (null != shaft)
{
System.Diagnostics.Debug.WriteLine("Equals called for " + this.Name + ". Compared with " + shaft.Name);
}
else
{
System.Diagnostics.Debug.WriteLine("Equals called for " + this + ". Compared with " + shaft);
}
return base.Equals(shaft);
}
}
}
This shows that the combobox is not releasing the objects binded to Itemsource even if the list is null. Until we implements IEquatable .
Any idea why it is like that?