Wpf 多么合适<;T>;影响combobox的行为

Wpf 多么合适<;T>;影响combobox的行为,wpf,combobox,system.componentmodel,Wpf,Combobox,System.componentmodel,在操作组合框时,我发现了一个有线问题。Xaml看起来像这样 <ComboBox x:Name="cb" ItemsSource="{Binding MyEntity.Choices}" SelectedItem="{Binding MyEntity.Choice,Mode=TwoWay}" Height="25" HorizontalAlignment="Stretch"

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

<ComboBox x:Name="cb" ItemsSource="{Binding MyEntity.Choices}" 
              SelectedItem="{Binding MyEntity.Choice,Mode=TwoWay}" 
              Height="25" 
              HorizontalAlignment="Stretch"
              VerticalAlignment="Top"/>
现在,如果我在Shaft上实现IEquatable&然后将列表设置为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);
        }
    }
}
公共类轴:可满足
{
私人内部id;
私有字符串\u名称;
公共整数Id{
获取{return\u id;}
设置{
_id=值;
}
}
公共字符串名
{
获取{return\u name;}
设置
{
_名称=值;
}
}
公共重写字符串ToString()
{
返回_name;
}
公共布尔等于(轴)
{
System.Diagnostics.Debug.WriteLine(“从object.Equals调用”);
//轴=obj作为轴;
如果(空!=轴)
{
System.Diagnostics.Debug.WriteLine(“为“+this.Name+”调用的等于。与“+shaft.Name”相比);
}
其他的
{
System.Diagnostics.Debug.WriteLine(“为“+this+”调用的相等值。与“+shaft”相比);
}
返回底座。等于(轴);
}
}
}
这表明即使列表为空,组合框也不会释放绑定到Itemsource的对象。 直到我们实现IEquatable


知道为什么会这样吗?

两种实现中单击按钮时的行为是相同的。如果在第二种情况下没有重写Object.Equals,您怎么知道没有调用它

至于不“释放”对象,这似乎是WPF的一个已知问题:

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

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

你必须更加具体。我不太明白你在说什么,尤其是为什么ComboBox调用Equals。@Stephen我的问题是为什么ComboBox即使设置为null也不释放ItemsSource中的对象?我找到了一个解决方法,如果我实现IEquatable,那么它工作得很好,但不知道为什么会出现这种行为。我知道Object.Equals没有被调用(当我使用IEquatable时),因为我在Equals中使用了调试点。我也用ObservaleCollection测试过,行为是一样的。我也看过微软的文章。它主要讨论绑定PropertyDescriptor,但在我的例子中,我绑定到属性。@Deep:在第二种情况下,您没有Object.Equals方法,只有IEquatable.Equals,因此不可能在那里设置断点。如果您在第二种情况下尝试了其他代码,您能展示一下吗?@Deep:PropertyDescriptor在您绑定到常规属性时由WPF内部使用,这就是为什么一篇文章讨论它的原因。我已经费劲地解释了您关于object.equals的问题。实际上,当我实现IEquatable时,我并没有覆盖Object.Equals。是否需要重写Object.Equals,以防我们实现IEquatable?@Deep:好的,这是一个很好的实践,可以提供一致的Object.Equals、IEquatable和运算符“==”和“!=”的实现。不管怎么说,问题是你是怎么知道这个对象的。如果你没有实现它,那么在第二种情况下没有调用Equals?实际上,这两种情况下的行为几乎相同。但是,在这种情况下,对象释放与平等实现没有任何关系。这个问题是由KB文章中描述的原因引起的。
 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);
    }
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);
        }
    }
}