Мне нужно обрабатывать только имена столбцов конкретной выбранной таблицы - PullRequest
2 голосов
/ 08 июля 2019

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

enter image description here

Когда я выбираю следующую таблицу из списка, я получаю столбцы новой таблицы плюс предыдущую из первой таблицы.

enter image description here

Как это исправить и сохранить только выбранные столбцы таблицы?

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

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

    foreach (DataGridViewColumn column in dataGridView1.Columns)
    {
        var item = (ToolStripMenuItem)contextMenuStrip1.Items.Add(column.HeaderText);
        var item2 = comboBox2.Items.Add(column.HeaderText);
        item.Tag = column.Name;
        item.Checked = column.Visible;
        item.CheckOnClick = true;

        item.CheckedChanged += (obj, args) =>
        {
            var i = (ToolStripMenuItem)obj;
            dataGridView1.Columns[(string)i.Tag].Visible = i.Checked;
        };
    }            
}

1 Ответ

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

Вам необходимо очистить коллекцию Items от contextMenuStrip1 перед ее заполнением.Это может быть просто сделано с помощью contextMenuStrip1.Items.Clear(), однако, чтобы предотвратить возможную утечку памяти / дескриптор памяти в вашем приложении, лучше располагать пункты меню сразу после их удаления:

var items = contextMenuStrip1.Items.Cast<ToolStripItem>().ToList();
contextMenuStrip1.Items.Clear();
items.ForEach(x => x.Dispose());

Пример

Вот рабочий пример, которому нужны DataGridView, ComboBox и ContextMenuStrip.Он загружает таблицы базы данных в ComboBox, и когда вы выбираете индекс из ComboBox, он загружает данные выбранной таблицы в DataGridView, и если вы щелкнете правой кнопкой мыши по заголовкам столбцов DataGridView,ContextMenuStrip будет показано, что позволяет вам установить видимость столбцов:

string server = ".";
string db = "TestDB";
private void Form1_Load(object sender, System.EventArgs e)
{
    var connection = $"SERVER={server};DATABASE={db};Integrated Security=true";

    //Hanlde combo box selected index changed
    comboBox1.SelectedIndexChanged += (obj1, args1) =>
    {
        dataGridView1.DataSource = null;
        if (comboBox1.SelectedIndex > -1)
        {
          //Fill data table and show data in data grid view
          var data = GetDataTable($"SELECT * FROM {comboBox1.SelectedValue}", connection);
          dataGridView1.Columns.Clear();
          dataGridView1.DataSource = data;
        }

        //Clear existing items of context menu strip
        var items = contextMenuStrip1.Items.Cast<ToolStripItem>().ToList();
        contextMenuStrip1.Items.Clear();
        items.ForEach(x => x.Dispose());

        //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;
            };
        }
    };

    //Load table names
    var tables = GetDataTable("SELECT Name FROM Sys.Tables", connection);
    comboBox1.ValueMember = "Name";
    comboBox1.DisplayMember = "Name";
    comboBox1.DataSource = tables;

    //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);
    };
}

DataTable GetDataTable(string commandText, string connectionString)
{
    using (var da = new SqlDataAdapter(commandText, connectionString))
    {
        var dt = new DataTable();
        da.Fill(dt);
        return dt;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...