Reputation: 89
I have a combobox in winform which gets data by calling a stored procedure in MySQL.
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'
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
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
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
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