Во время работы со списком я обнаружил проблему с проводной связью. Xaml выглядит так
<ComboBox x:Name="cb" ItemsSource="{Binding MyEntity.Choices}"
SelectedItem="{Binding MyEntity.Choice,Mode=TwoWay}"
Height="25"
HorizontalAlignment="Stretch"
VerticalAlignment="Top"/>
Предположим, что Itemsource связан со списком валов (объект), а selectedItem - один из списка.
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;
}
И затем я попытался сделать этот список нулевым (пожалуйста, обратитесь к Button_Click). Combobox вызывает .Equals для каждого объекта списка и сравнивает последний выбранный объект.
Хотя я ожидаю, что он не должен вызывать .equals и устанавливать SelectedItem на ноль.
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);
}
Теперь, если я реализую IEquatable на Shaft, а затем установлю для List значение null, все будет нормально. Означает, что вызов не выполняется .Eqauls & selectedItem имеет значение null.
Новая реализация
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);
}
}
}
Это показывает, что выпадающий список не освобождает объекты, связанные с Itemsource, даже если список пуст.
Пока мы не реализуем IEquatable.
Есть идеи, почему это так?