저는 C # Visual Studio 2010에서 사용자 정의 컨트롤을 개발 중입니다. 즉, datagridview를 필터링하기위한 일종의 "빠른 찾기"텍스트 상자입니다. DataTable, DataBinding 및 DataSet의 3 가지 유형의 datagridview 데이터 소스에 대해 작동해야합니다. 내 문제는 DataGridView에 표시되는 DataSet 개체에서 DataTable을 필터링하는 것입니다.
3 가지 경우 (DataGridView 및 TextBox가있는 표준 WinForm 응용 프로그램의 예)가있을 수 있습니다. 처음 2 개는 정상적으로 작동하고 세 번째 경우에는 문제가 있습니다.
1. datagridview.DataSource = dataTable : 다음과
같이 설정하여 필터링 할 수 있도록 작동 합니다. dataTable.DefaultView.RowFilter = "country 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 = "country 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을 추가 한 다음 set 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 변경됨) datagridview가 업데이트되지 않습니다 ... 어떤 솔루션을 오랫동안 찾고 있었지만 문제는 DataSource가 변경 -추가 제어이므로 프로그래머의 코드를 엉망으로 만들고 싶지 않습니다.
가능한 해결책은 다음과 같습니다.
-DataBinding을 사용하여 DataSet에서 DataTable을 바인딩하고 예제 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());
}
MessageBox의 dataSource가 변경되는 것처럼 허용되지 않습니다.
프로그래머가 다음과 비슷한 코드를 작성할 수 있기 때문에 그렇게하고 싶지 않습니다.
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
}
디자이너에서 DataSet 및 DataMember를 사용하여 DataGridView를 디자인했기 때문에 그렇게 할 수 있습니다. 코드는 컴파일되지만 필터를 사용한 후에는 예외가 발생합니다.
그래서 질문은 : 어떻게 DataSet에서 DataTable을 필터링하고 DataSource를 다른 것으로 변경하지 않고 DataGridView에 결과를 표시 할 수 있습니까? DataSet에서 DataTable 필터링이 작동하지 않는 동안 예제 1에서 DataTable을 직접 필터링 할 수있는 이유는 무엇입니까? 이 경우 DataGridView에 바인딩 된 DataTable이 아닐까요?
내 문제는 디자인 문제에서 발생하므로 솔루션은 예제 3에서 작동해야합니다.