Setting DataRow as a ComboBox Value Member

I am filling items in my ComboBox from an XML file using a DataTable. I currently set it up so that one column is displayed in the ComboBox and the other is a member-value. However, this may not always work for me as I have to set the selectedItem parameter and the value item may not be unique.

I don't know if there is a duplicate value item in the table or not, so I thought I would put the entire DataRow as a ComboBox value member and then use ComboBox.SelectedITem = (DataRow) some_data_row; to select and it will always select the correct ComboBox object.

How would I do it? Is there a better way to do this? I am open to suggestions however it is very important that I can get to both, display member and value element.

Thanks for your help!

EDIT . Maybe I wasn't clear enough before, but while I'm asking if there is a better approach here, I'm also asking how to do it. If I do not set the valuemember parameter, the SelectedItem is of type DataRowView ... Note that I want to use the selectedValue parameter to select items from the ComboBox, and if I try to do so without explicitly setting the value of the an parameter an exception is thrown.

+1


source to share


3 answers


First of all, thanks to Adam Robinson, I'm sure your answer was correct, but that was not what I wanted to hear. I solved my problem in a different way, and I think it might be useful to someone else, so I am posting it here.

What I did was create a new class, in my case I named it ListObject, which had a DataRow property (as you will see later, it works for other types too, I just used that since this is what I really wanted as the Item property). It also overrides methods:

  • String ToString ()
  • bool Equals (obj object)
  • int GetHashCode () - not needed in my case, however Visual Studio
    warns you that this should be canceled.

The idea was that I could populate the ComboBox.Items collections with objects of my own class, display a custom row (if I didn't work that way, my next stack overflow question was probably about setting DisplayMembers when reading items from the DataRow) and only compare one class element (in my case DataRow).

So here's the code and it works great (at least for what I wanted to do with it).

public class ListObject
{
    public DataRow element;

    public String DisplayObject = null;

    public ListObject(DataRow dr)
    {
        element = dr;
    }

    public ListObject(DataRow dr, String dspObject)
    {
        element = dr;
        DisplayObject = dspObject;
    }

    public override String ToString()
    {
        if (DisplayObject == null) throw new Exception("DisplayObject property was not set.");

        return element[DisplayObject].ToString();
    }

    public override bool Equals(object obj)
    {
        if (obj.GetType() == typeof(ListObject))
            return Equals(((ListObject)obj).element, this.element);
        else return base.Equals(obj);
    }

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

      



This works fine in my case, since I can just fill the ComboBox with a foreach statement:

dtUsers.ReadXml(Program.Settings.xmlInputUsers);

foreach(DataRow dr in dtUsers.Rows) 
{
    cmbUser.Items.Add(new ListObject(dr, "Name"));
}

      

And when I get the DataRow I want to select, I just do this:

cmbUser.SelectedItem = new ListObject(dlg.SelectedDataRow);

      

Where I dont need to worry about DisplayMember etc. because only the DataRow will be compared and your display options will still be set after you have populated the ComboBox.Items collection. Also, since the toString method is overridden, you can actually customize your output.

The creation of this class was only possible because of the msdn article on ComboBox.SelectedItem, which noted that the SelectedItem property works using the IndexOf method. This method uses the Equals method to determine equality.

0


source


If you bind ListBox

to DataTable

, you actually bind it to DataView

, which represents that DataTable

( DataTable

implements IListSource

and returns a DataView

)), you cannot set SelectedItem

to an instance directly DataRow

, you must set it to an instance DataRowView

. Unfortunately, there is no easy way to get DataRowView

from a DataRow

.

Your best bet is to make all your interactions through DataRowView

. This will allow you to explicitly install SelectedItem

.



You cannot use a property SelectedValue

, you must use SelectedItem

for that.

+1


source


This is the easiest way to get DataTable in combobox

private void load() { 
DataTable dt = // get data from DB 
comboBox1.ValueMember = null; // allows you to get all fields in the obj to combobox
comboBox1.DisplayMember = "ccType";//label displayed from dt
comboBox1.DataSource = dt;
}
//to test 
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
    {

        DataRowView current = (DataRowView)comboBox1.SelectedValue;
        string drs = current.Row["ID"].ToString();

    }

      

0


source







All Articles