C# 以编程方式添加DataGridView列

C# 以编程方式添加DataGridView列,c#,winforms,datagridview,contextmenu,C#,Winforms,Datagridview,Contextmenu,我有一个充满产品信息的DataGridView。datagridview总共有50列,但是用户并不总是需要所有的列,我想帮助他们选择要显示哪些列和不显示哪些列 我想编程的一个解决方案是,当用户右键单击列时,他们可以从弹出的列表中选择要显示的列和不显示的列。如下图所示。 我该怎么做呢。非常感谢您的帮助。您可以使用WinForms ContextMenuStrip和DataGridView列的Visible属性来实现这一点 下面是一些示例代码,可以满足您的要求: namespace Windows

我有一个充满产品信息的DataGridView。datagridview总共有50列,但是用户并不总是需要所有的列,我想帮助他们选择要显示哪些列和不显示哪些列

我想编程的一个解决方案是,当用户右键单击列时,他们可以从弹出的列表中选择要显示的列和不显示的列。如下图所示。


我该怎么做呢。非常感谢您的帮助。

您可以使用WinForms ContextMenuStrip和DataGridView列的Visible属性来实现这一点

下面是一些示例代码,可以满足您的要求:

namespace WindowsFormsApplication4
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            BindingList<User> users = new BindingList<User>{
                  new User{Name = "John", Address="Home Street", Title="Mr."},
                  new User{Name = "Sally", Address="Home Street", Title="Mrs."}
            };

            contextMenuStrip1.AutoClose = true;       
            contextMenuStrip1.Closing += new ToolStripDropDownClosingEventHandler(contextMenuStrip1_Closing);

            dataGridView1.DataSource = users;

            dataGridView1.DataBindingComplete += new DataGridViewBindingCompleteEventHandler(dataGridView1_DataBindingComplete);
        }

        void dataGridView1_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
        {

            foreach (DataGridViewColumn gridViewColumn in this.dataGridView1.Columns)
            {
                ToolStripMenuItem item = new ToolStripMenuItem();
                item.Name = gridViewColumn.Name;
                item.Text = gridViewColumn.Name;
                item.Checked = true;
                item.CheckOnClick = true;
                item.CheckedChanged += new EventHandler(item_CheckedChanged);
                contextMenuStrip1.Items.Add(item);
            }

            foreach (DataGridViewColumn gridViewColumn in this.dataGridView1.Columns)
            {
                gridViewColumn.HeaderCell.ContextMenuStrip = contextMenuStrip1;
            }

        }

        void item_CheckedChanged(object sender, EventArgs e)
        {
            ToolStripMenuItem item = sender as ToolStripMenuItem;

            if (item != null)
            {
                dataGridView1.Columns[item.Name].Visible = item.Checked;
            }
        }

        void contextMenuStrip1_Closing(object sender, ToolStripDropDownClosingEventArgs e)
        {
            if (e.CloseReason == ToolStripDropDownCloseReason.ItemClicked)
            {
                e.Cancel = true;
            }
        }
    }

    public class User
    {
        public string Name { get; set; }
        public string Address { get; set; }
        public string Title { get; set; }
    }

}
命名空间窗口窗体应用程序4
{
公共部分类Form1:Form
{
公共表格1()
{
初始化组件();
BindingList用户=新建BindingList{
新用户{Name=“John”,Address=“Home Street”,Title=“Mr.”},
新用户{Name=“Sally”,Address=“Home Street”,Title=“Mrs.”
};
contextMenuStrip1.AutoClose=true;
contextMenuStrip1.Closing+=新工具StripDropDownClosingEventHandler(contextMenuStrip1_Closing);
dataGridView1.DataSource=用户;
dataGridView1.DataBindingComplete+=新的DataGridViewBindingCompleteEventHandler(dataGridView1_DataBindingComplete);
}
void dataGridView1_DataBindingComplete(对象发送方,DataGridViewBindingCompleteEventTarget e)
{
foreach(此.dataGridView1.Columns中的DataGridViewColumn gridViewColumn)
{
ToolStripMenuItem项=新的ToolStripMenuItem();
item.Name=gridViewColumn.Name;
item.Text=gridViewColumn.Name;
item.Checked=true;
item.CheckOnClick=true;
item.CheckedChanged+=新事件处理程序(item_CheckedChanged);
contextMenuStrip1.Items.Add(item);
}
foreach(此.dataGridView1.Columns中的DataGridViewColumn gridViewColumn)
{
gridViewColumn.HeaderCell.ContextMenuStrip=contextMenuStrip1;
}
}
无效项\u CheckedChanged(对象发送方,事件参数e)
{
ToolStripMenuItem=发件人作为ToolStripMenuItem;
如果(项!=null)
{
dataGridView1.Columns[item.Name].Visible=item.Checked;
}
}
void contextMenuStrip1_关闭(对象发送方,ToolStripDropDownClosingEventArgs e)
{
如果(e.CloseReason==ToolStripDropDownCloseReason.ItemClicked)
{
e、 取消=真;
}
}
}
公共类用户
{
公共字符串名称{get;set;}
公共字符串地址{get;set;}
公共字符串标题{get;set;}
}
}
这里的用户类就是示例编译的对象,它提供了绑定DataGridView的内容

我还添加了一些代码,允许用户一次单击多个列(通过在关闭时检查关闭原因,如果是项目选择则取消)。在我看来,这实际上有点偏离了标准UI行为——通常坚持使用标准行为会更好,但我将其包括在内,因为它(我认为)在这个场景中很有用


此外,将这种定制放在从DataGridView继承的新控件中通常更为整洁

这是干什么用的?Asp.net、WPF、WinForms?@MikeTeeVee-用于winforms@Erika-datagridview具有可以使用的双击事件。但是,一旦您离标准ui如此之远,我建议您使用其他控件,而不是上下文菜单-您可以在双击时打开显示列列表的模式窗体。@Ekira不确定为什么会发生这种情况。这不会发生在我的测试代码中,我猜这与您现有的上下文菜单有关-也许可以考虑从databindingcomplete中删除上下文菜单创建,或者在那里进行检查以确保只添加新列。@Erika您是什么意思,记得吗?在我的测试应用程序中,它只是在上下文菜单中自己工作——如果它不适合您,那么您的一些代码正在删除该功能。此外,网格列的Visible属性本质上存储了这些信息。为了记住表单关闭后的内容,您需要一些其他机制,例如存储字典的主表单,或某种形式的持久性(特别是如果您希望关闭应用程序并在关闭后记住所选内容)@Erika为此,您需要将选中列和未选中列的列表存储在表单之外的其他位置。这实际上取决于应用程序的其余部分——如果您没有自己的想法,那么可能值得再问一个问题。有很多地方可以存储用户数据,但每个地方都有其优点和缺点,值得详细讨论。@Erika但这只是数据-您只需要存储用户id和选中列的列表。