Фильтрация BindingList - PullRequest
       33

Фильтрация BindingList

0 голосов
/ 18 апреля 2019

В C # WinForms у меня есть две DataGrids, отображающие табличные данные. Первый отображает все строки, второй должен отображать отфильтрованный набор этих строк. Мне нужно построить отфильтрованное представление на моем экземпляре представления BindingList. Это представление необходимо обновить после изменения базового списка.

Я пытался создать новый экземпляр BindingList с помощью LINQ и Where. но фильтрованный не обновляется при изменении базового myList.

var filtered = new BindingList<Clip>(myList.Where<Clip>
(
c => c.participant.Contains(id)
).ToList<Clip>());

Как я могу это сделать? Спасибо

1 Ответ

2 голосов
/ 18 апреля 2019

BindingList<T> не поддерживает фильтрацию (по крайней мере, не напрямую), поэтому я предлагаю заменить ваш BindingList на DataTable. DataView поддерживает фильтрацию, а отфильтрованные данные - это просто пользовательское подмножество того же DataTable.

В этом примере два класса BindingSource используются для привязки одного DataTable к двум элементам управления DataGridView.
Один из классов BindingSource привязан к отфильтрованному DataView DataTable, используясвойство DataView.RowFilter , выражение , которое принимает подмножество SQL-подобных команд.

Здесь второй DataGridView.DataSource установлен на BindingSource, у которого его DataSource связан с отфильтрованным DataView.
Фильтр определяется с использованием определенного значения ("Value A1") второго столбца.(Column1).

В визуальном примере видно, что два элемента управления DataGridView обновляют значения своих ячеек, когда значения ячеек обоих DataGridView изменяются.
Кроме того, фильтр активен для второго DataGridView: строкифильтруются при изменении значений фильтруемых столбцов.

DataGridView filtered BindingSource

Чтобы проверить это поведение, добавьте 2 элемента управления DataGridView в форму, добавьте кнопку (здесь с именем btnBind) и подпишитесь на Click событие с обработчиком btnBind_Click.

private BindingSource dgvBindingSource1 = null;
private BindingSource dgvBindingSource2 = null;
private DataTable dt = null;

private void btnBind_Click(object sender, EventArgs e)
{
    FillData(3, 3);
    dgvBindingSource1 = new BindingSource(dt, null);

    DataView dv = dt.AsDataView();
    dv.RowFilter = "Column1 = 'Value A1'";
    dgvBindingSource2 = new BindingSource(dv, null);

    dataGridView1.DataSource = dgvBindingSource1;
    dataGridView2.DataSource = dgvBindingSource2;
}

private void FillData(int cols, int rows)
{
    dt = new DataTable("TestTable");
    dt.Columns.AddRange(Enumerable.Range(0, cols)
              .Select(i => new DataColumn("Column" + i.ToString(), typeof(string))).ToArray());

    for (int r = 0; r < rows; r++) {
        dt.Rows.Add(Enumerable.Range(0, cols)
               .Select(n => $"Value {(char)('A' + r)}" + n.ToString()).ToArray());
    }
}
...