Лишние строки появляются в DataGridView после применения фильтра TreeView. - PullRequest
0 голосов
/ 22 октября 2019

Проблема с отображением строк после применения фильтра. В DataGridView я использую динамическое обновление.

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

problem image

Важно отметить, что обновления таблицы не происходят в основном потоке;Обновление происходит с фиксированным интервалом 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 "Category":
                    mainForm.dataGridView1.CurrentCell = null;
                    for (int i = 0; i < mainForm.dataGridView1.Rows.Count; i++)
                    {
                        mainForm.dataGridView1.Rows[i].Visible = true;
                    }
                    break;
                case "MED":
                    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 "Air":
                    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 отображается только нужный набор строк). Реализация через метод DataGridView1_CellValueChanged и новый поток private void ThreeViewMarker():

 Invoke((MethodInvoker)delegate
            {
                switch (TreeView1.SelectedNode.Text)
                {
                    case "Category":
                        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 "MED":
                        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 "Air":
                        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();
                            }
                        }

... и т. Д.

Этот метод также работает не так, как следует по аналогии с предыдущим методом.

По-прежнему непонятное поведение формы в целом, проблема при масштабировании окна (появляется первая строка из набора):

scaling

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

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

.gif описание:

  • Категория - категория
  • МЭД - Эквивалентная доза (в ru Мощность эквивалентной дозы )
  • Воздух - Воздух
  • Спец. контроль - специальный контроль
  • Не работает - Не работает

  • Уставки - порог

  • Предаварийная - до аварии
  • Аварийная - авария

Чтобы решить проблему, я попытался использовать это:

string columnName = "type"; // or other column
string filterValue = "2";   // or other value
string rowFilter = string.Format("[{0}] = '{1}'", columnName, filterValue);
(mainForm.dataGridView1.DataSource as DataTable).DefaultView.RowFilter = rowFilter;

Но в этом случае скрытые строки больше не опрашиваются (они, кажется, отсутствуютиз DataSource или что-то в этом роде)

Спасибо за помощь;Я прошу прощения за мой английский ... =)

Ответы [ 2 ]

1 голос
/ 23 октября 2019

Мне удалось воспроизвести проблему.

problem.gif

Дополнительная строка - это строка, выбранная в CurencyManager и выделенная треугольником.

Варианты решения:

  • Отключить CurrencyManager в начале метода фильтрации

    CurrencyManager currencyManager = (CurrencyManager)BindingContext [dataGridView1.DataSource];
    currencyManager.SuspendBinding();
    

    Треугольник заголовка исчезнет (но тогда он не будет работать дляиспользуйте CurrentRow и CurrentCell в некоторых случаях и, возможно, что-то еще).

  • Переключите строку на ту, которая должна быть видимой.

    dataGridView1.CurrentCell = this.dataGridView1[columnNumber, visibleRowNumber];
    

    Но это не работаетв случае, когда все строки должны быть скрыты.

solution.gif

0 голосов
/ 22 октября 2019

Попробуй это.

  • Добавьте свойство видимости в свой BindingSource и привяжите видимость каждой строки к свойству видимости.
  • Отключить RaiseListChangedEvents и возобновить их после, а также сбросить привязки, чтобы сетка могла обновлять себя.

    CurrencyManager currencyManager = (CurrencyManager) BindingContext [dataGridView1.DataSource];

    currencyManager.RaiseListChangedEvents = false ;

    // Отключить все остальные строки, установив для свойства видимости значение false в источнике привязки

    currencyManager.RaiseListChangedEvents = true ;

    currencyManager. ResetBindings ();

Проверить это: https://docs.microsoft.com/en-us/dotnet/api/system.windows.forms.datagridview.databindingcomplete?redirectedfrom=MSDN&view=netframework-4.8

Использование события DataBindingComplete для отключения / включения строк

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...