IEQuatable <t>如何影响组合框的行为</t>

时间:2011-03-14 07:35:12

标签: wpf combobox system.componentmodel

在使用组合框时,我发现了一个有线问题。 Xaml看起来像这样

<ComboBox x:Name="cb" ItemsSource="{Binding MyEntity.Choices}" 
              SelectedItem="{Binding MyEntity.Choice,Mode=TwoWay}" 
              Height="25" 
              HorizontalAlignment="Stretch"
              VerticalAlignment="Top"/>

让我们说Itemsource被绑定一个Shaft(对象)列表&amp; 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;
}

然后我尝试将此列表设为null(请参阅Button_Click).Combobox正在调用List&amp;的每个对象的.Equals。比较最后一个Selected对象。 虽然我的期望是不应该打电话给.equals&amp;将SelectedItem设置为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);
    }

现在如果我在Shaft&amp;上实现IEquatable然后将List设置为null它可以正常工作。意味着没有电话.Eqauls&amp; 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。

知道为什么会这样吗?

1 个答案:

答案 0 :(得分:0)

Button_Click上的行为对于两种实现都是相同的。如果在第二种情况下没有覆盖它,你怎么知道没有对Object.Equals的调用?

至于不“释放”对象,这看起来是一个已知的WPF问题:http://support.microsoft.com/kb/938416

作为解决方法,您可以执行以下操作之一:

  • 调用Collection.Clear方法,而不是将集合引用设置为null
  • 使用ObservableCollection而不是Collection