Установите видимость столбцов DataGridView, используя CheckedListBox - PullRequest
4 голосов
/ 05 июля 2019

Я занимаюсь разработкой приложения для формы 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;
}

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

Ответы [ 2 ]

5 голосов
/ 06 июля 2019

Если у вас есть столбцы в 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;
};

enter image description here

На всякий случай, если вы заинтересованы в этом, используя 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);
};

enter image description here

1 голос
/ 05 июля 2019

Вы можете начать с заполнения 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;не уверен, как я это пропустил ;-).Это, очевидно, намного лучше, так как не нужно проходить все пункты ..

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