Установите видимость столбцов DataGridView с помощью CheckedListBox

Я разрабатываю приложение формы Windows, управляющее базой данных SQL Server. Когда я щелкаю поле со списком, которое заполнено всеми таблицами, я добавляю все столбцы из выбранной таблицы в поле списка, а затем, когда я проверяю, чтобы следующий столбец исчез. Я застрял здесь.

private void ComboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
        var tableName = comboBox1.SelectedItem;

        SqlDataAdapter sqlDa = new SqlDataAdapter($"SELECT * FROM {tableName}", form1.conn = new SqlConnection($"Server = {form1.ServerBox.Text }; Database = { form1.DBBox.Text}; Trusted_Connection = True"));

        DataTable dataTable = new DataTable();
        sqlDa.Fill(dataTable);

        string comboQuery = $"SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = N'{tableName}'";

        using (form1.conn = new SqlConnection($"Server = {form1.ServerBox.Text }; Database = { form1.DBBox.Text}; Trusted_Connection = True"))
        {
            form1.conn.Open();

            using (SqlCommand cmd = new SqlCommand(comboQuery, form1.conn))
            {
                using (SqlDataReader reader = cmd.ExecuteReader())
                {
                    checkedListBox1.Items.Clear();

                    while (reader.Read())
                    {
                        checkedListBox1.Items.Add((string)reader["COLUMN_NAME"]);
                    }
                }
            }

            form1.conn.Close();
        }

        dataGridView1.DataSource = dataTable;
}

Спасибо, за потраченное время!

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

Ответы 2

Вы можете начать с заполнения CheckedListBox, может быть, так:

checkedListBox1.Items.Clear   
checkedListBox1.Items.AddRange(dataGridView1.Columns.Cast<DataGridViewColumn>()
                                                    .Select(x => x.Name)
                                                    .ToArray());

for (int i = 0; i < checkedListBox1.Items.Count; i++)
{
    checkedListBox1.SetItemChecked(i, true);
}
checkedListBox1.CheckOnClick = true;

Теперь вы можете закодировать событие checkedListBox1_SelectedIndexChanged так:

for (int i = 0; i < checkedListBox1.Items.Count; i++)
{
    dataGridView1.Columns[i].Visible =
       checkedListBox1.GetItemCheckState(i) == CheckState.Checked;
}

Обновлять Реза нашел событие ItemCheck; не уверен, как я пропустил это ;-). Это, очевидно, намного лучше, так как не нужно просматривать все элементы.

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

Когда у вас есть столбцы в DataGridView, вам не нужно снова загружать их с сервера SQL, и, как уже показано в другом ответе, вы можете получить имена столбцов из DataGridView.

Чтобы добавить столбцы в CheckedListBox, я предпочитаю использовать DataSource, DisplayMember и ValueMember, чтобы показать столбец HeaderText в CheckedListBox, имея доступ к их именам, чтобы иметь возможность найти их в DataGridView.

Затем я бы установил начальное состояние проверки элементов на основе видимости соответствующего столбца.

Затем я обрабатываю событие ItemCheck и нахожу имя столбца на основе отмеченного элемента и устанавливаю видимость столбца на основе нового состояния проверки:

//Add the columns to checked list box
var columns = dataGridView1.Columns.Cast<DataGridViewColumn>()
    .Select(x => new { x.Name, x.HeaderText }).ToList();
checkedListBox1.DataSource = columns;
checkedListBox1.ValueMember = "Name";
checkedListBox1.DisplayMember = "HeaderText";

//Set initial check state based on columns visibility
for (int i = 0; i < checkedListBox1.Items.Count; i++)
{
    dynamic item = checkedListBox1.Items[i];
    checkedListBox1.SetItemChecked(i, dataGridView1.Columns[(string)item.Name].Visible);
}

//Hanlde ItemCheck event
checkedListBox1.ItemCheck += (obj, args) =>
{
    dynamic item = checkedListBox1.Items[args.Index];
    var visible = args.NewValue == CheckState.Checked ? true : false;
    dataGridView1.Columns[(string)item.Name].Visible = visible;
};

На всякий случай, если вам интересно сделать это, используя ContextMenuStrip:

//Add the columns to context menu strip
foreach (DataGridViewColumn c in dataGridView1.Columns)
{
    var item = (ToolStripMenuItem)contextMenuStrip1.Items.Add(c.HeaderText);
    item.Tag = c.Name;
    item.Checked = c.Visible;
    item.CheckOnClick = true;

    //Hanlde CheckStateChanged event of context menu strip items
    item.CheckStateChanged += (obj, args) =>
    {
        var i = (ToolStripMenuItem)obj;
        dataGridView1.Columns[(string)i.Tag].Visible = i.Checked;
    };
}

//Show context menu strip on right click on data grid veiw header
dataGridView1.CellMouseClick += (obj, args) =>
{
    if (args.RowIndex == -1 && args.Button == MouseButtons.Right)
        contextMenuStrip1.Show(Cursor.Position);
};

Но когда я меняю значение на другую таблицу, все они сохраняются, и если у меня есть, например, в первой таблице «ID», а во втором «Имя» и «Номер», все они сохраняются в ToolStripMenu, и я только потребность в выбранной таблице.

user11612444 08.07.2019 10:55

Если вы поместите код в Load обработчик событий вашей формы и у вас есть dataGridView1 и contextMenuStrip1, он будет работать правильно. Верно? Значит для dataGridView2, нужно contextMenuStrip2.

Reza Aghaei 08.07.2019 11:10

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

user11612444 08.07.2019 11:50

Я могу представить некоторые возможные ошибки в коде, но я не уверен в вашем коде. давайте оставим этот пост как есть (поскольку этот кусок кода является бесплатным для поста и не является основным ответом на ваш вопрос) и зададим новый вопрос, включая минимальный воспроизводимый пример, чтобы воспроизвести проблему и описать ожидаемое поведение, тогда я или, может быть, другой участник сообщества поможет вам решить проблему :)

Reza Aghaei 08.07.2019 11:56

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