Обновление DataGridView с помощью выбора ComboBox

У меня есть DataGridView (называемый SummaryDataGrid) в классе форм Windows (называемый SummaryForm), который я пытаюсь программно обновить с помощью раскрывающегося списка ComboBox (называемого YearComboBox). SummaryDataGrid не редактируется пользователем и просто используется для отображения информации в виде электронной таблицы. Я хочу иметь возможность использовать YearComboBox, чтобы пользователь мог выбрать год, а затем SummaryDataGrid обновить его значения на основе выбора этого года. Вы можете увидеть скриншот SummaryForm по ссылке ниже, показывающий SummaryDataGrid, заселенный к 2020 году.

Сводная форма просмотра

YearComboBox не привязан к данным, как и SummaryDataGrid. Чтобы заполнить SummaryDataGrid программно, я создаю DataGridViewRows в SummaryForm, а затем заполняю данные, извлекая их из моей базы данных SQL, используя функции, определенные в моем MainForm, которые, в свою очередь, используют функции, определенные в моем наборе данных, который связан с моим SQL Server, который я размещаю. Некоторые примеры кода можно найти ниже.

public partial class SummaryForm : Form
{
    private DataGridViewRow JanuaryRow = new DataGridViewRow();
    private DataGridViewRow FebruaryRow = new DataGridViewRow();
    private DataGridViewRow MarchRow = new DataGridViewRow();
    private DataGridViewRow AprilRow = new DataGridViewRow();
    private DataGridViewRow MayRow = new DataGridViewRow();
    private DataGridViewRow JuneRow = new DataGridViewRow();
    private DataGridViewRow JulyRow = new DataGridViewRow();
    private DataGridViewRow AugustRow = new DataGridViewRow();
    private DataGridViewRow SeptemberRow = new DataGridViewRow();
    private DataGridViewRow OctoberRow = new DataGridViewRow();
    private DataGridViewRow NovemberRow = new DataGridViewRow();
    private DataGridViewRow DecemberRow = new DataGridViewRow();
    private DataGridViewRow TotalRow = new DataGridViewRow();
    private DataGridViewRow AverageRow = new DataGridViewRow();

    private int year = DateTime.Today.Year;
    ...
    // form load event handler
    private void SummaryForm_FormLoad(Object sender, EventArgs e)
    {
        YearComboBox.Text = year.ToString();

        JanuaryRow.CreateCells(SummaryDataGrid);
        FebruaryRow.CreateCells(SummaryDataGrid);
        MarchRow.CreateCells(SummaryDataGrid);
        AprilRow.CreateCells(SummaryDataGrid);
        MayRow.CreateCells(SummaryDataGrid);
        JuneRow.CreateCells(SummaryDataGrid);
        JulyRow.CreateCells(SummaryDataGrid);
        AugustRow.CreateCells(SummaryDataGrid);
        SeptemberRow.CreateCells(SummaryDataGrid);
        OctoberRow.CreateCells(SummaryDataGrid);
        NovemberRow.CreateCells(SummaryDataGrid);
        DecemberRow.CreateCells(SummaryDataGrid);
        TotalRow.CreateCells(SummaryDataGrid);
        AverageRow.CreateCells(SummaryDataGrid);

        // populate january row
        JanuaryRow.Cells[0].Value = "January";
        JanuaryRow.Cells[1].Value = MainFormInstance.BillsOfSaleCountMonth(1, year);
        JanuaryRow.Cells[2].Value = MainFormInstance.BillsOfSaleCashMonth(1, year);
        JanuaryRow.Cells[3].Value = MainFormInstance.BillsOfSaleCreditMonth(1, year);
        JanuaryRow.Cells[4].Value = Convert.ToDecimal(JanuaryRow.Cells[2].Value) + Convert.ToDecimal(JanuaryRow.Cells[3].Value);
        JanuaryRow.Cells[5].Value = MainFormInstance.CashMonth(1, year);
        JanuaryRow.Cells[6].Value = MainFormInstance.CardMonth(1, year);
        JanuaryRow.Cells[7].Value = MainFormInstance.MonthCP(1, year);
        JanuaryRow.Cells[8].Value = MainFormInstance.ExpensesMonthCP(1, year) + MainFormInstance.BillsOfSaleCashMonth(1, year);
        JanuaryRow.Cells[9].Value = Convert.ToDecimal(JanuaryRow.Cells[7].Value) - Convert.ToDecimal(JanuaryRow.Cells[8].Value);
        JanuaryRow.Cells[10].Value = MainFormInstance.MonthCF(1, year);
        JanuaryRow.Cells[11].Value = MainFormInstance.ExpensesMonthCF(1, year);
        JanuaryRow.Cells[12].Value = Convert.ToDecimal(JanuaryRow.Cells[10].Value) - Convert.ToDecimal(JanuaryRow.Cells[11].Value);
        JanuaryRow.Cells[13].Value = MainFormInstance.ExpensesMonthGeneral(1, year);
        JanuaryRow.Cells[14].Value = Convert.ToDecimal(JanuaryRow.Cells[5].Value) + Convert.ToDecimal(JanuaryRow.Cells[6].Value);
        JanuaryRow.Cells[15].Value = Convert.ToDecimal(JanuaryRow.Cells[8].Value) + Convert.ToDecimal(JanuaryRow.Cells[11].Value) + Convert.ToDecimal(JanuaryRow.Cells[13].Value);
        JanuaryRow.Cells[16].Value = Convert.ToDecimal(JanuaryRow.Cells[14].Value) - Convert.ToDecimal(JanuaryRow.Cells[15].Value);
        SummaryDataGrid.Rows.Add(JanuaryRow);
        ...
    }

    // year combo box selection event handler
    private void SummaryForm_YearChanged(Object sender, EventArgs e)
    {
        year = int.Parse(YearComboBox.Text);
        PopulateSummaryDataGrid();
    }

    // populate the summary data grid
    private void PopulateSummaryDataGrid()
    {
        // stubbed
    }

Я определил обработчик событий SelectedValueChanged для YearComboBox и сначала попытался перенести заполнение каждой строки в отдельную функцию из обработчика событий FormLoad. Идея заключалась в том, чтобы обработчик события FormLoad обновлял начальный атрибут Text YearComboBox из переменной года, определенной в SummaryForm, выполнял вызовы CreateCells() для каждой строки, а затем вызывал отдельную функцию void для выполнения заполнения. Однако при отладке отдельная функция немедленно достигала бы первого оператора JanuaryRow, пытающегося отредактировать ячейку, и сообщала бы, что индекс равен -1 и, следовательно, выходит за пределы допустимого диапазона. Я попытался просто запустить событие SelectedValueChanged для обработчика событий FormLoad, но это тоже не сработало из-за того, что строка уже была создана и заполнена.

Итак, мой вопрос: как я могу просто получить этот раскрывающийся список, чтобы изменить год, используемый операторами в обработчике событий FormLoad (который отлично работает), и повторно заполнить DataGridView новыми значениями на основе обновленного года?

Вы пробовали очистить свой datagriview? SummaryDataGrid.Rows.Clear(); СводкаДанных.Обновить(); также вы можете извлечь коды, которые добавляют строки в datagridview к методу вместо того, чтобы делать это при загрузке

Cagri D. Kaynar 22.12.2020 21:31

Я рад, что вы нашли решение, но я должен спросить, есть ли причина, по которой вы хотите, чтобы код повторно собирал данные каждый раз, когда пользователь меняет год? Неизвестно, сколько лет находится в поле со списком, но сбор всех данных за годы ОДИН РАЗ и сохранение их в контейнере, таком как DataSet или List<T>, кажется лучшим подходом. Ручное добавление столбцов и строк в сетку при каждом изменении в поле со списком просто кажется излишним, когда вы можете вернуть контейнер, используя свой текущий код… вместо того, чтобы записывать в сетку, записывайте в DataTable и сохраняйте его… просто предложение. Удачи.

JohnG 23.12.2020 05:57

@JohnG В программе всего два года, 2020 и 2021. На 2021 год пока нет данных. Данные хранятся в DataSet, который взаимодействует с установленным SQL Server, на котором хранится вся информация. Переключение между годами — довольно редкое явление для пользователя, обычно они просто хотят загрузить текущий год, который загружается в обработчике событий FormLoad. Иногда пользователь может захотеть вернуться к предыдущему году, просто чтобы посмотреть на рост или сезонные тенденции. Как единственный пользователь этой программы, она работает по мере необходимости таким образом.

Matthew Lowery 23.12.2020 22:22

@JohnG Кроме того, чтобы было ясно, строки создаются и добавляются только один раз в обработчике событий FormLoad. В ответе на мой вопрос, который я опубликовал, я узнал, как просто редактировать ячейки DataGridView непосредственно в отдельном методе, который вызывается обработчиком событий поля со списком, и это решило мою проблему.

Matthew Lowery 23.12.2020 22:25
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
4
97
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ну, кажется, я наткнулся на решение, пробуя разные вещи. Может быть, не самая элегантная, но вот моя реализация PopulateSummaryGrid() на случай, если кто-то еще столкнется с этой проблемой:

// populate the summary data grid
    private void PopulateSummaryDataGrid()
    {
        // update January row
        SummaryDataGrid.Rows[0].Cells[1].Value = MainFormInstance.BillsOfSaleCountMonth(1, year);
        SummaryDataGrid.Rows[0].Cells[2].Value = MainFormInstance.BillsOfSaleCashMonth(1, year);
        SummaryDataGrid.Rows[0].Cells[3].Value = MainFormInstance.BillsOfSaleCreditMonth(1, year);
        SummaryDataGrid.Rows[0].Cells[4].Value = Convert.ToDecimal(SummaryDataGrid.Rows[0].Cells[2].Value) + Convert.ToDecimal(SummaryDataGrid.Rows[0].Cells[3].Value);
        SummaryDataGrid.Rows[0].Cells[5].Value = MainFormInstance.CashMonth(1, year);
        SummaryDataGrid.Rows[0].Cells[6].Value = MainFormInstance.CardMonth(1, year);
        SummaryDataGrid.Rows[0].Cells[7].Value = MainFormInstance.MonthCP(1, year);
        SummaryDataGrid.Rows[0].Cells[8].Value = MainFormInstance.ExpensesMonthCP(1, year) + MainFormInstance.BillsOfSaleCashMonth(1, year);
        SummaryDataGrid.Rows[0].Cells[9].Value = Convert.ToDecimal(SummaryDataGrid.Rows[0].Cells[7].Value) - Convert.ToDecimal(SummaryDataGrid.Rows[0].Cells[8].Value);
        SummaryDataGrid.Rows[0].Cells[10].Value = MainFormInstance.MonthCF(1, year);
        SummaryDataGrid.Rows[0].Cells[11].Value = MainFormInstance.ExpensesMonthCF(1, year);
        SummaryDataGrid.Rows[0].Cells[12].Value = Convert.ToDecimal(SummaryDataGrid.Rows[0].Cells[10].Value) - Convert.ToDecimal(SummaryDataGrid.Rows[0].Cells[11].Value);
        SummaryDataGrid.Rows[0].Cells[13].Value = MainFormInstance.ExpensesMonthGeneral(1, year);
        SummaryDataGrid.Rows[0].Cells[14].Value = Convert.ToDecimal(SummaryDataGrid.Rows[0].Cells[5].Value) + Convert.ToDecimal(SummaryDataGrid.Rows[0].Cells[6].Value);
        SummaryDataGrid.Rows[0].Cells[15].Value = Convert.ToDecimal(SummaryDataGrid.Rows[0].Cells[8].Value) + Convert.ToDecimal(SummaryDataGrid.Rows[0].Cells[11].Value) + Convert.ToDecimal(SummaryDataGrid.Rows[0].Cells[13].Value);
        SummaryDataGrid.Rows[0].Cells[16].Value = Convert.ToDecimal(SummaryDataGrid.Rows[0].Cells[14].Value) - Convert.ToDecimal(SummaryDataGrid.Rows[0].Cells[15].Value);
        ...
        SummaryDataGrid.Refresh();
    }

Мне также пришлось удалить первый оператор моего обработчика событий FormLoad, который устанавливал текст YearComboBox в текущий год. Это, кажется, все работает правильно.

Я рад слышать, что ваша проблема решена, вы можете нажать «✔», чтобы отметить свой ответ как ответ.

Jack J Jun 28.12.2020 09:53

Другие вопросы по теме