1
votes

I'm learning WinForm, and in a recent practice, I wanted to realize such a function: A ComboBox with some other controls in form. And ComboBox's DisplayMember is the "Name" of each control, and the ValueMember is their "Handle". Like this. Application Picture

However, it didn't work so well, and when I debug, I found the after binding the DataSource, the DisplayMember shows a empty string. Debug

Also the ValueMember setting shows error if I set it "Handle".

Are there any rules when using these two properties?

Code are as follow.

cmbAllControls.DataSource = allControlsList;//DataSource, List<Control>.
cmbAllControls.DisplayMember = "Name";
cmbAllControls.ValueMember = "TabIndex";//TabIndex is OK, but Handle will throw error.
1
Controls' Properties are returned in very different manners. A Control's Text, for example, is returned using GetWindowText(). Try to use the "Text" property as the DisplayMember. You might be surprised. You could (should) use a simple custom class, with some Properties (i.e., Name (string), Handle (IntPtr) and Control (Control). Use a List<class> as the ComboBox.DataSource. You can then access all the properties of any Control casting SelectedItem to your custom class Type. - Jimi
Btw, I suggested the Text property becase that property is browsable. Also, possibly, set the DisplayMember and ValueMember before you set the DataSource. - Jimi

1 Answers

0
votes

Seems to be related to the Browseable(false attribute) on Handle. When I try the code below it works fine if I remove the attribute but crashes with ArgumentException "Cannot bind to the new value member."

public Form1()
{
    InitializeComponent();

    comboBox1.DataSource = new List<MyObj>()
    {
        new MyObj(){Name = "Fish",MyInt = 3,MyIntPtr = new IntPtr(5),MyIntPtr2 = new IntPtr(7)}
    };

    comboBox1.DisplayMember = "Name";
    comboBox1.ValueMember = "MyIntPtr";
    comboBox1.ValueMember = "MyIntPtr2";
    comboBox1.SelectedIndexChanged += (s, e) => { MessageBox.Show("Selected:" + comboBox1.SelectedValue); };
}

private class MyObj
{
    public string Name { get; set; }
    public int MyInt { get; set; }
    public IntPtr MyIntPtr { get; set; }

    [System.ComponentModel.Browsable(false)] //This attribute causes the error
    public IntPtr MyIntPtr2 { get; set; }
}