数据绑定组合框选择项目似乎不起作用

时间:2009-06-12 09:12:42

标签: .net vb.net winforms data-binding

我正在尝试将组合绑定到对象集合:

    Dim t As New TradeOrderStatus()
    Dim ts As List(Of TradeOrderStatus) = t.GetStatuses

    With Me.cboTradeStatus
        .DataSource = ts
        .SelectedItem = Nothing
    End With

这很好用,我看到了组合中的项目列表。但是,当我尝试将组合的SelectedItem设置为以下项目之一时:

Me.cboTradeStatus.SelectedItem = Trade.TradeStatus
没有任何反应。 Trade.TradeStatus是TradeOrderStatus类的实例,所有必需属性都在下拉列表中可见。 SelectedItem保持为Nothing(如果我从绑定代码中省略.SelectedItem = Nothing行,则保留为列表中的第一项)。

Debug.Print(CStr(Me.cboTradeStatus.Items.Contains(.TradeStatus)))

也会返回false。有人可以帮忙吗?

3 个答案:

答案 0 :(得分:4)

  

Trade.TradeStatus是TradeOrderStatus类的实例

你提到它是一堂课;是相同的实例是数据绑定列表中的那个实例吗?它需要找到一个相等的匹配。或者,您可以覆盖Equals(和GetHashCode() - 始终保持两者同步)以实现相同的目标。


(编辑)

解决问题的最简单方法是绑定到SelectedValue;使用“完整”示例(如下所示),例如:

cbo.DisplayMember = cbo.ValueMember = "Name";    
...
btn.Click += delegate { cbo.SelectedValue = GetCurrentStatus().Name; };

(编辑)

这是一个C#示例(抱歉,我的VB-fu很弱)提供不同状态的自定义相等 - 请注意“取消注释”:

using System.Windows.Forms;
using System.Collections.Generic;

class MyStatus {
    public MyStatus(string name) { Name = name; }
    public string Name { get; private set; }
    public override string ToString() {return Name; }
    /* uncomment to fix
    public override bool Equals(object obj) {
        MyStatus other = obj as MyStatus;
        return other != null && other.Name == this.Name;
    }
    public override int GetHashCode() {return Name.GetHashCode(); }
    */
}
static class Program {
    static void Main() {
        ComboBox cbo = new ComboBox();
        cbo.DataSource = GetStatuses();
        Button btn = new Button();
        btn.Click += delegate { cbo.SelectedItem = GetCurrentStatus(); };
        btn.Text = "Set Status";
        btn.Dock = DockStyle.Bottom;
        Application.Run(new Form { Controls = { cbo, btn } });
    }
    static List<MyStatus> GetStatuses() {
        List<MyStatus> stats = new List<MyStatus>();
        stats.Add(new MyStatus("Open"));
        stats.Add(new MyStatus("Pending"));
        stats.Add(new MyStatus("Closed"));
        return stats;
    }
    static MyStatus GetCurrentStatus() {
        return new MyStatus("Closed");
    }
}

答案 1 :(得分:0)

根据Marc的回答在这里回答我自己的问题。我已经将给定的样本转换为VB等价物:

Public Overloads Overrides Function Equals(ByVal obj As Object) As Boolean
        ' Check for null values and compare run-time types.
        If obj Is Nothing Or Not Me.GetType() Is obj.GetType() Then
            Return False
        End If

        Dim t As TradeOrderStatus = CType(obj, TradeOrderStatus)
        Return Me.ID = t.ID

    End Function


    Public Overrides Function GetHashCode() As Integer
        Return Me.GetHashCode()
    End Function

我的组合绑定现在按预期工作。

答案 2 :(得分:0)

当我在C#中使用上面的GetHashCode()解决方案时,我从无限循环中获得了堆栈溢出:

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

你的意思是改为:

return this.Id;

当我做出这个改变时,它起作用了。这真是一个痛苦所以这里是C#中的代码,对于任何拥有null DataSource且需要覆盖ComboBox中的GetHashCode和Equals方法的人来说:

using System.Windows.Forms;

namespace Ace.Docs.UI.ComboBoxes
{
    internal class DisplayInfo : ComboBox
    {
        #region Properties (2) 

        public string DisplayName { get; set; }

        public int Id { get; set; }

        #endregion Properties 

        #region Methods (2) 

        // Public Methods (2) 

        public override bool Equals(object obj)
        {
            // Check for null values and compare run-time types. 
            if (obj == null | (!object.ReferenceEquals(this.GetType(), obj.GetType())))
            {
                return false;
            }
            var t = (DisplayInfo)obj;
            return this.Id == t.Id;
        }

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

        #endregion Methods 
     }
}