Проблема, которую вы описываете, имеет две стороны. Во-первых, код «добавляет» столбец флажка к самому DataGridView
! Это проблема, потому что DataSource
в сетке не «ЗНАЕТ» об этом «добавленном» столбце. Поэтому, когда вы применяете «фильтр» к источнику данных, этот фильтр не будет знать о столбце флажка и, очевидно, НЕ будет поддерживать / заботиться о том, какие флажки были отмечены или не установлены. Чтобы сохранить флажки в фильтре, столбец флажка должен находиться в самом источнике данных.
Во-вторых, кажется, что когда пользователь изменяет текст в текстовом поле фильтра, этот код - повторный запрос к базе данных. Это странно, и я уверен, что вы можете подумать об этом. Пример: каждый раз, когда пользователь вводит символ в текстовое поле, код повторно запрашивает базу данных. Если пользователь хочет «набрать» 123, то… когда пользователь вводит «1», база данных запрашивается, затем снова, когда пользователь вводит «2», и снова, когда пользователь вводит «3». Это, очевидно, не является необходимым и может быть классифицировано как забивание базы данных.
Не поймите меня неправильно, в том смысле, что мы ХОЧЕМ «фильтровать» данные, когда пользователь вводит «1», затем « 2 »и, наконец,« 3 »... вы просто не хотите повторно запрашивать базу данных, чтобы сделать это. Во избежание этого разброса базы данных код мог бы создать «глобальную» переменную, которая хранит ОРИГИНАЛЬНЫЕ данные, затем, когда мы хотим отфильтровать данные, вместо повторного запроса к базе данных, вы можете получить отфильтрованную копию ОТ ОРИГИНАЛЬНЫХ данных , Это будет означать, что код будет запрашивать базу данных только один раз.
Учитывая это, приведенный ниже код демонстрирует добавление столбца флажка к сеткам DataSource
DataTable
… не к самой сетке. Это сохранит флажки при фильтрации. Кроме того, вместо повторного запроса к базе данных при вводе каждого символа фильтра код фильтрует исходный источник данных. Это достигается созданием нового DataView
из исходных данных, а затем фильтрацией, который DataView
для каждого введенного символа.
Надеюсь, что это помогает и имеет смысл.
Метод загрузки формы может выглядеть например ...
DataSet ds;
public Form1() {
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e) {
ds = new DataSet();
ds.Tables.Add(GetDataFromDB());
ds.Tables[0].Columns.Add("Select", typeof(bool));
dataGridView1.DataSource = ds.Tables[0];
}
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * DataTable
1 * Затем мы добавляем столбец к DataTable
, возвращаемому из базы данных. Этот столбец называется «Выбрать» и имеет тип bool
… столбец флажка. Теперь флажки будут сохраняться при фильтрации.
Наконец, чтобы «фильтровать» данные, когда пользователь вводит текст в текстовое поле фильтра…
private void textBox1_TextChanged(object sender, EventArgs e) {
DataView dv = new DataView(ds.Tables[0]);
if (double.TryParse(textBox1.Text, out double value)) {
dv.RowFilter = "CONVERT(Title, 'System.String') LIKE('" + value + "%')";
}
dataGridView1.DataSource = dv;
}
Здесь мы создаем «новый ”DataView
из исходных данных, затем отфильтруйте это DataView
, используя текст в текстовом поле, затем установите сетку на этот новый DataView
. Следует отметить, что метод double.TryParse
используется для фильтрации любого текста, который пользователь вводит, который НЕ является числом или является пустым; в этом случае фильтр отобразит ВСЕ данные.
Для завершения этого примера ниже приведен метод получения некоторых тестовых данных для тестирования.
private DataTable GetDataFromDB() {
DataTable dt = new DataTable();
dt.TableName = "Titles";
Random rand = new Random();
dt.Columns.Add("Title", typeof(double));
for (int i = 0; i < 3000; i++) {
dt.Rows.Add(rand.Next(0, 1000));
}
return dt;
}