В DataGridView появляются лишние строки после применения фильтра TreeView, как исправить?

Возникла проблема с отображением отфилтрованных через TreeView строк в DataGridVIew.

Суть проблемы: после применения фильтра, например, по условию сделать Rows.Visible = true строки, которые соответствуют, а несоответствие Rows.Visible = false, появляются другие строки, причем отображаются не полностью, а только их обновлённые ячейки, как на примере:

5dad34cd8c488502205105.png

Важно отметить, что обновление DataGridView у меня происходит не в main потоке, т.е. я постоянно обновляю что-то в таблице по заданному thread_delay_time.

Код, который отрабатывает в методе TreeView1_AfterSelect:

private void TreeView1_AfterSelect(object sender, TreeViewEventArgs e)
    {
        Classes.TreeViewFilter treeViewFilter = new Classes.TreeViewFilter();
        treeViewFilter.Filter(this);
    }


Кусок из класса TreeViewFilter:

class TreeViewFilter
        {
            public void Filter(MainForm mainForm)
            {
                switch (mainForm.TreeView1.SelectedNode.Text)
                {
                    case "Категория":
                        mainForm.dataGridView1.CurrentCell = null;
                        for (int i = 0; i < mainForm.dataGridView1.Rows.Count; i++)
                        {
                            mainForm.dataGridView1.Rows[i].Visible = true;
                        }
                        break;
                    case "МЭД":
                        mainForm.dataGridView1.CurrentCell = null;
                        for (int i = 0; i < mainForm.dataGridView1.Rows.Count; i++)
                        {
                            if (Convert.ToInt32(mainForm.dataGridView1.Rows[i].Cells[13].Value) == 1)
                                mainForm.dataGridView1.Rows[i].Visible = true;
                            else
                                mainForm.dataGridView1.Rows[i].Visible = false;
                        }
                        break;
                    case "Воздух":
                        mainForm.dataGridView1.CurrentCell = null;
                        for (int i = 0; i < mainForm.dataGridView1.Rows.Count; i++)
                        {
                            if (Convert.ToInt32(mainForm.dataGridView1.Rows[i].Cells[13].Value) == 2)
                                mainForm.dataGridView1.Rows[i].Visible = true;
                            }
                            else
                                mainForm.dataGridView1.Rows[i].Visible = false;


... и тд, все остальное по аналогии

Фильтрация мне нужна не только по After_Select, но и динамическая, что бы при выбранном узле TreeView в DataGridView отображался только нужный набор строк, реализовывал я это через DataGridView1_CellValueChanged и новый поток private void ThreeViewMarker() в котором все делалось по аналогии, но с небольшими изменениями, т.к. выскакивал exception:

Invoke((MethodInvoker)delegate
                {
                    switch (TreeView1.SelectedNode.Text)
                    {
                        case "Категория":
                            dataGridView1.CurrentCell = null;
                            for (int i = 0; i < dataGridView1.Rows.Count; i++)
                            {
                        CurrencyManager currencyManager = (CurrencyManager)BindingContext[dataGridView1.DataSource];
                        currencyManager.SuspendBinding();
                        dataGridView1.Rows[i].Visible = true;
                        currencyManager.ResumeBinding();
                            }
                            break;
                        case "МЭД":
                            dataGridView1.CurrentCell = null;
                            for (int i = 0; i < dataGridView1.Rows.Count; i++)
                            {
                                if (Convert.ToInt32(dataGridView1.Rows[i].Cells[13].Value) == 1)
                                {
                            CurrencyManager currencyManager = (CurrencyManager)BindingContext[dataGridView1.DataSource];
                            currencyManager.SuspendBinding();
                            dataGridView1.Rows[i].Visible = true;
                            currencyManager.ResumeBinding();
                                }
                                else
                                {
                            CurrencyManager currencyManager = (CurrencyManager)BindingContext[dataGridView1.DataSource];
                            currencyManager.SuspendBinding();
                            dataGridView1.Rows[i].Visible = false;
                            currencyManager.ResumeBinding();
                                }
                            }
                            break;
                        case "Воздух":
                            dataGridView1.CurrentCell = null;
                            for (int i = 0; i < dataGridView1.Rows.Count; i++)
                            {
                                if (Convert.ToInt32(dataGridView1.Rows[i].Cells[13].Value) == 2)
                                {
                            CurrencyManager currencyManager = (CurrencyManager)BindingContext[dataGridView1.DataSource];
                            currencyManager.SuspendBinding();
                            dataGridView1.Rows[i].Visible = true;
                            currencyManager.ResumeBinding();
                                }
                                else
                                {
                            CurrencyManager currencyManager = (CurrencyManager)BindingContext[dataGridView1.DataSource];
                            currencyManager.SuspendBinding();
                            dataGridView1.Rows[i].Visible = false;
                            currencyManager.ResumeBinding();
                                }
                            }


... и тд, дальше по аналогии.

Естественно, этот метод так же не отрабатывает как следует, появляются лишние строки.

Имеет место быть еще и странное поведение строк после применения фильтра в целом, проблема проявляется при масштабировании окна немного другим образом и появляется первая строка из набора строк:

5dad3584e4923520515099.gif

На .gif метод с динамическим обновлением DataGridView отключен! Результат простого After_Select.

Подскажите, пожалуйста, как с этим бороться и что я не учел при подобной фильтрации.

Спасибо.
  • Вопрос задан
  • 343 просмотра
Решения вопроса 1
SpacePurr
@SpacePurr
c#, wpf
На сколько я понял, лишняя строка, которая появляется - это выделенная строка в CurrencyManager.
Я смог найти два подхода к решению этой проблемы:
  • Отключить CurrencyManager в начале метода фильтрации по дереву
    CurrencyManager currencyManager = (CurrencyManager)BindingContext [dataGridView1.DataSource];
    currencyManager.SuspendBinding();

    Отключение сделает недоступным некоторые возможности, например CurrentRow, CurrentCell и, возможно, еще что-то.

  • Переключать выделение на одну из строк, которые должны быть видимыми.
    dataGridView1.CurrentCell = this.dataGridView1[columnNumber, visibleRowNumber];

    Однако, этот вариант не работает в случае, когда все строки должны быть скрыты.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы