Winforms组合框错误 - 具有相同值但不同键的2个项目

时间:2015-04-22 20:42:24

标签: vb.net winforms

这真的是2015年Winforms中的一个错误,还是我做错了......

1)创建一个新的winforms项目(.net 4.0)并将一个组合框添加到主窗体。 2)将此用于表单加载代码:

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load

    Dim items As New Dictionary(Of Integer, String)

    items.Add(1, "Value 1")
    items.Add(2, "Value 2")
    items.Add(3, "Value 3")
    items.Add(4, "Value 3")

    Dim dataSource As New BindingSource(items, Nothing)
    ComboBox1.DataSource = dataSource

    ComboBox1.DisplayMember = "Value"
    ComboBox1.ValueMember = "Key"

End Sub

注意第3项和第3项的内容。 4具有相同的值,但不同的键和显示和值成员设置正确(除非我疯了,这是可能的)。运行应用程序时,打开组合框并选择最后一项。现在,打开组合框备份,你会发现现在选择了倒数第二个项目。这是一个问题。

有什么想法吗?

谢谢!

编辑:我在表单中添加了一个Infragistics UltraComboEditor,并将以下代码放在表单加载事件中:

    For Each item As KeyValuePair(Of Integer, String) In items
        UltraComboEditor1.Items.Add(New ValueListItem With {.DataValue = item.Key, .DisplayText = item.Value})
    Next

    UltraComboEditor1.SelectedIndex = 0
    UltraComboEditor1.AutoComplete = True

Infragistics控件允许我自动完成并输入我自己的文本,当我选择与其上方项目具有相同文本的项目时,它不会更改我的选择。 Winforms控件不应该像我那样改变我的选择。

1 个答案:

答案 0 :(得分:1)

ComboBox允许编辑文本部分时,它将模式匹配并突出显示匹配的第一个前缀文本。这具有副作用,当关闭列表框时,所选项目将更新。

ComboBox's DropDownStyle == DropDownList模式时,之前选中的项目将在下拉列表中突出显示。

您可以通过将NativeWindow分配到list窗口来更改行为,然后收听LB_SETCURSEL Msg

您可以使用此主题作为起点:Prevent AutoSelect behavior of a System.Window.Forms.ComboBox (C#)

向Data对象添加int index字段。然后在Register方法中添加:

    combo.SelectedIndexChanged += delegate {
        data.index = combo.SelectedIndex;
    };

然后将Data传递给本机窗口,该窗口会跟踪先前选择的索引。

private class NW : NativeWindow {
    Data data;
    public NW(IntPtr handle, Data data) {
        this.AssignHandle(handle);
        this.data = data;
    }

    private const int LB_FINDSTRING = 0x018F;
    private const int LB_FINDSTRINGEXACT = 0x01A2;
    private const int LB_SETCURSEL = 0x0186;

    protected override void WndProc(ref Message m) {
        if (m.Msg == LB_FINDSTRING)
            m.Msg = LB_FINDSTRINGEXACT;

        if (m.Msg == LB_SETCURSEL)
            m.WParam = (IntPtr) data.index;

        base.WndProc(ref m);
    }
}