ฉันกำลังพัฒนาการควบคุมผู้ใช้ใน C # Visual Studio 2010 ซึ่งเป็นช่องข้อความ "ค้นหาอย่างรวดเร็ว" สำหรับการกรอง datagridview ควรใช้กับแหล่งข้อมูล datagridview 3 ประเภท ได้แก่ DataTable, DataBinding และ DataSet ปัญหาของฉันคือการกรอง DataTable จากวัตถุ DataSet ซึ่งแสดงบน DataGridView
อาจมี 3 กรณี (ตัวอย่างสำหรับแอปพลิเคชัน WinForm มาตรฐานที่มี DataGridView และ TextBox อยู่) - 2 รายการแรกทำงานได้ดีฉันมีปัญหากับอันที่ 3:
1. datagridview.DataSource = dataTable: มันใช้งานได้
ดังนั้นฉันจึงสามารถกรองโดยการตั้งค่า: dataTable.DefaultView.RowFilter = "ประเทศ LIKE '% s%'";
DataTable dt = new DataTable();
private void Form1_Load(object sender, EventArgs e)
{
dt.Columns.Add("id", typeof(int));
dt.Columns.Add("country", typeof(string));
dt.Rows.Add(new object[] { 1, "Belgium" });
dt.Rows.Add(new object[] { 2, "France" });
dt.Rows.Add(new object[] { 3, "Germany" });
dt.Rows.Add(new object[] { 4, "Spain" });
dt.Rows.Add(new object[] { 5, "Switzerland" });
dt.Rows.Add(new object[] { 6, "United Kingdom" });
dataGridView1.DataSource = dt;
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
MessageBox.Show("DataSource type BEFORE = " + dataGridView1.DataSource.GetType().ToString());
dt.DefaultView.RowFilter = string.Format("country LIKE '%{0}%'", textBox1.Text);
MessageBox.Show("DataSource type AFTER = " + dataGridView1.DataSource.GetType().ToString());
}
2. datagridview.DataSource = bindingSource: มันใช้งานได้
ดังนั้นฉันจึงสามารถกรองโดยการตั้งค่า: bindingSource.Filter = "ประเทศ LIKE '% s%'";
DataTable dt = new DataTable();
BindingSource bs = new BindingSource();
private void Form1_Load(object sender, EventArgs e)
{
dt.Columns.Add("id", typeof(int));
dt.Columns.Add("country", typeof(string));
dt.Rows.Add(new object[] { 1, "Belgium" });
dt.Rows.Add(new object[] { 2, "France" });
dt.Rows.Add(new object[] { 3, "Germany" });
dt.Rows.Add(new object[] { 4, "Spain" });
dt.Rows.Add(new object[] { 5, "Switzerland" });
dt.Rows.Add(new object[] { 6, "United Kingdom" });
bs.DataSource = dt;
dataGridView1.DataSource = bs;
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
MessageBox.Show("DataSource type BEFORE = " + dataGridView1.DataSource.GetType().ToString());
bs.Filter = string.Format("country LIKE '%{0}%'", textBox1.Text);
MessageBox.Show("DataSource type AFTER = " + dataGridView1.DataSource.GetType().ToString());
}
3. datagridview.DataSource = dataSource; datagridview.DataMember = "TableName": มันใช้ไม่ได้
มันเกิดขึ้นเมื่อคุณออกแบบตารางโดยใช้ตัวออกแบบ: ใส่ DataSet จากกล่องเครื่องมือในแบบฟอร์มเพิ่ม dataTable เข้าไปแล้วตั้งค่า datagridview.DataSource = dataSource; และ datagridview.DataMember = "TableName"
โค้ดด้านล่างหลอกว่าการดำเนินการเหล่านี้:
DataSet ds = new DataSet();
DataTable dt = new DataTable();
private void Form1_Load(object sender, EventArgs e)
{
dt.Columns.Add("id", typeof(int));
dt.Columns.Add("country", typeof(string));
dt.Rows.Add(new object[] { 1, "Belgium" });
dt.Rows.Add(new object[] { 2, "France" });
dt.Rows.Add(new object[] { 3, "Germany" });
dt.Rows.Add(new object[] { 4, "Spain" });
dt.Rows.Add(new object[] { 5, "Switzerland" });
dt.Rows.Add(new object[] { 6, "United Kingdom" });
ds.Tables.Add(dt);
dataGridView1.DataSource = ds;
dataGridView1.DataMember = dt.TableName;
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
MessageBox.Show("DataSource type BEFORE = " + dataGridView1.DataSource.GetType().ToString());
//it is not working
ds.Tables[0].DefaultView.RowFilter = string.Format("country LIKE '%{0}%'", textBox1.Text);
MessageBox.Show("DataSource type AFTER = " + dataGridView1.DataSource.GetType().ToString());
}
หากคุณทดสอบ - แม้ว่า datatable จะถูกกรอง (ds.Tables [0] .DefaultView.Count changes) datagridview ไม่ได้รับการอัปเดต ... ฉันมองหาวิธีแก้ปัญหามานานแล้ว แต่ปัญหาคือDataSource ไม่สามารถ เปลี่ยน - เนื่องจากเป็นการควบคุมเพิ่มเติมฉันไม่ต้องการให้มันยุ่งกับรหัสของโปรแกรมเมอร์
ฉันรู้วิธีแก้ปัญหาที่เป็นไปได้คือ
- เพื่อผูก DataTable จาก DataSet โดยใช้ DataBinding และใช้เป็นตัวอย่างที่ 2: แต่ขึ้นอยู่กับโปรแกรมเมอร์ในระหว่างการเขียนโค้ด
- เพื่อเปลี่ยน dataSource เป็น BindingSource, dataGridView.DataSource = dataSet.Tables [0] หรือ เป็น DefaultView โดยทางโปรแกรมอย่างไรก็ตามจะเปลี่ยน DataSource ดังนั้นวิธีแก้ปัญหา:
private void textBox1_TextChanged(object sender, EventArgs e)
{
MessageBox.Show("DataSource type BEFORE = " + dataGridView1.DataSource.GetType().ToString(), ds.Tables[0].DefaultView.Count.ToString());
DataView dv = ds.Tables[0].DefaultView;
dv.RowFilter = string.Format("country LIKE '%{0}%'", textBox1.Text);
dataGridView1.DataSource = dv;
MessageBox.Show("DataSource type AFTER = " + dataGridView1.DataSource.GetType().ToString(), ds.Tables[0].DefaultView.Count.ToString());
}
ไม่เป็นที่ยอมรับดังที่คุณเห็นใน dataSource ของ MessageBox กำลังเปลี่ยนแปลง ...
ฉันไม่ต้องการทำเช่นนั้นเพราะเป็นไปได้ที่โปรแกรมเมอร์จะเขียนโค้ดในลักษณะนี้:
private void textBox1_TextChanged(object sender, EventArgs e)
{
MessageBox.Show("DataSource type BEFORE = " + dataGridView1.DataSource.GetType().ToString(), ds.Tables[0].DefaultView.Count.ToString());
DataSet dsTmp = (DataSet)(dataGridView1.DataSource); //<--- it is OK
DataView dv = ds.Tables[0].DefaultView;
dv.RowFilter = string.Format("country LIKE '%{0}%'", textBox1.Text);
dataGridView1.DataSource = dv; //<--- here the source is changeing from DataSet to DataView
MessageBox.Show("DataSource type AFTER = " + dataGridView1.DataSource.GetType().ToString(), ds.Tables[0].DefaultView.Count.ToString());
dsTmp = (DataSet)(dataGridView1.DataSource); //<-- throws an exception: Unable to cast object DataView to DataSet
}
เขาทำได้ในขณะที่เขาออกแบบ DataGridView ด้วย DataSet และ DataMember ในดีไซน์เนอร์ โค้ดจะถูกคอมไพล์อย่างไรก็ตามหลังจากใช้ตัวกรองแล้วจะมีข้อยกเว้น ...
คำถามคือ: ฉันจะกรอง DataTable ใน DataSet และแสดงผลลัพธ์บน DataGridView โดยไม่เปลี่ยน DataSource เป็นอื่นได้อย่างไร เหตุใดฉันจึงสามารถกรอง DataTable จากตัวอย่างที่ 1 ได้โดยตรงในขณะที่การกรอง DataTable จาก DataSet ไม่ทำงาน อาจจะไม่ใช่ DataTable ที่ผูกไว้กับ DataGridView ในกรณีนั้น?
โปรดทราบว่าปัญหาของฉันเกิดจากปัญหาในการออกแบบดังนั้นวิธีแก้ปัญหาต้องใช้ในตัวอย่างที่ 3