ARK
ARK

Reputation: 89

The combobox displays system.data.datarowview

I have a combobox in winform which gets data by calling a stored procedure in MySQL.

My stored proc:

CREATE PROCEDURE `GetCourses`()
BEGIN
SELECT course_name FROM my_db.courses where group_id=1;
END

Now the course names are bind with the Combobox(ComboBox2) as below - on selection of another Combobox(ComboBox1):

private void Form_Load(object sender, EventArgs e)
{
  var connectionString = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
  conn = new MySqlConnection(connectionString);
  conn.Open();
  MySqlCommand cmd1 = new MySqlCommand();
  cmd1.Connection = conn;
  cmd1.CommandType = CommandType.StoredProcedure;
  cmd1.CommandText = "GetCourses";
  DataTable dt1 = new DataTable();
  MySqlDataAdapter adp1 = new MySqlDataAdapter(cmd1);
  adp1.Fill(dt1);
}

private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
  if (comboBox1.SelectedIndex == 3)
  {
    comboBox2.ValueMember = "course_name";
    comboBox2.DisplayMember = "course_name";
    comboBox2.DataSource = dt1;
  }
}

But when I run the form, the ComboBox is filled with the values as 'system.data.datarowview'

Form

Could anyone please help me with this.

NOTE: I don't want to achieve this by using 'MySqlDataReader'

Thanks in advance.

Upvotes: 0

Views: 2719

Answers (3)

Calvinthesneak
Calvinthesneak

Reputation: 88

I ran a mock test, and I think it's disposing of your dataset(when it finished the OnLoad event) before you can get to the selectedIndex changed event. Try having your SelectedIndexChanged event raise a function to populate the second box. PS, don't mind I used an SQLite database to test.

Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged
        If (ComboBox1.SelectedIndex = 3) Then            
            Select3()    
        End If
    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load    
        Dim range() As String = {"0", "1", "2", "3 - Fire Combo2", "4", "5", "6"}
        ComboBox1.Items.AddRange(range)            
    End Sub

    Private Sub Select3()
        Dim connectionString As String = MyStandAloneDB.DBConnStr
        Dim conn As New System.Data.SQLite.SQLiteConnection(connectionString)
        conn.Open()
        Dim cmd1 As New System.Data.SQLite.SQLiteCommand
        cmd1.Connection = conn
        cmd1.CommandType = CommandType.Text
        cmd1.CommandText = "SELECT * FROM Foo"
        Dim dt1 As New DataTable()
        Dim adp1 As New System.Data.SQLite.SQLiteDataAdapter(cmd1)
        adp1.Fill(dt1)
        ComboBox2.DataSource = dt1
        ComboBox2.ValueMember = dt1.Columns(1).ToString
        ComboBox2.DisplayMember = dt1.Columns(0).ToString
    End Sub

Upvotes: 0

ARK
ARK

Reputation: 89

This is solved simply by below two lines of code.

private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
  if (comboBox1.SelectedIndex == 3)
  {
    foreach (DataRow row in dt1.Rows)
      comboBox2.Items.Add(row["course_name"]);
  }
}    

Upvotes: 1

Crowcoder
Crowcoder

Reputation: 11514

You could project the data into a collection that has named fields to prevent the default ToString()ing of the datarow objects:

 if (comboBox1.SelectedIndex == 3)
  {
    comboBox2.ValueMember = "course_name_value";
    comboBox2.DisplayMember = "course_name";
    comboBox2.DataSource = dt1.AsEnumerable().Select 
       (n => new { course_name = n["course_name"], course_name_value = n["course_name"]}).ToList();
  }

EDIT

I think you should put these lines in the Load event. You don't need to set them more than once, and it could be the reason for the combobox display getting the object's ToString() result instead of individual properties.

comboBox2.ValueMember = "course_name";
comboBox2.DisplayMember = "course_name";

Upvotes: 0

Related Questions