我正在尝试将组合绑定到对象集合:
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。有人可以帮忙吗?
答案 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
}
}