c# - 在 Designer 中使用时自定义 DataGridView 列重复

标签 c# .net winforms datagridview windows-forms-designer

我做了一个自定义的 DataGridView 组件,里面有一个标准的 DataGridViewImageColumn。当我不需要在特定表中时,新属性会更改列的可见性。我在构造函数中添加列并在 CellFormatting 事件中更新它。这是按预期工作的部分。

当我将控件放到一个新窗体上时,它会显示其中的新列。运行程序会在网格中生成两个图像列。

Screenshot in designer

一个新的表单只是添加了组件并设置了Dock.Fill

Screenshot from application running

当我在不做任何更改的情况下启动它时,它会显示两列。第一个正常工作,第二个总是显示丢失的 x 图像(其中没有数据,所以它们同时显示 x)。

在表单的设计器中有一个自动添加的图像列。

private CustomDataGridView customDataGridView1;
private System.Windows.Forms.DataGridViewImageColumn dataGridViewImageColumn1;

当我继续编辑表单时,有时会发生 VS 创建相同列的更多副本。要解决这个问题,我必须时不时地清除 DGV.Columns 列表。

如何防止 VS 复制我的字段?

以下代码是重现问题的最少部分。

public class CustomDataGridView : DataGridView
{
    private DataGridViewImageColumn EditStatusIcons;

    private bool hasIcons = true;
    public bool HasIcons
    {
        get { return this.hasIcons; }
        set
        {
            if (this.Columns["EditIcons"] == null) return;

            this.Columns["EditIcons"].Visible = value;
            this.hasIcons = value;
        }
    }

    public CustomDataGridView()
    {
        this.EditStatusIcons = new System.Windows.Forms.DataGridViewImageColumn();

        this.EditStatusIcons.HeaderText = "";
        this.EditStatusIcons.Name = "EditStatusIcons";

        this.Columns.Add(this.EditStatusIcons);
    }
}

编辑:我也尝试使用 this.AutoGenerateColumns = false; 就像 Custom DataGridView adds columns everytime I build说。没有任何变化。

清除表单上列出的列会删除工作列并留下一个列 dataGridViewImageColumn1,它只是一个名称错误的完整空列。

最佳答案

控件按预期运行。

原因

您在构造函数中添加了一个列,然后设计器将该列序列化。然后运行该应用程序,它会在构造函数中添加一列。所以你有 2 列。这样继续下去,不限于 2 列。即使您不需要构建和运行,打开包含网格的表单并对表单进行小的更改并保存就足够了。新专栏诞生!

解决方案

根据您的要求,要解决问题,您可以考虑以下选项:

  1. 检查控件是否处于设计模式,然后不添加该列,仅在运行时添加。

  2. 您可以检查控件是否包含现有的此类图像列,然后不要再添加一个。您可以通过某些属性的类型使列唯一。

  3. 您可以为控件创建自定义设计器,并将添加列的代码放在控件的初始化中。这样,代码仅在您第一次将控件添加到窗体时运行。


关于解决方案的一些说明

完全根据您的要求在解决方案之间进行选择,并且所有选项都可用。但是请考虑这些关于解决方案的注释:

  1. 关于第一个解决方案,不要使用 DesignMode 属性,因为它在构造函数中不起作用。而是以这种方式执行检查:

    if (System.ComponentModel.LicenseManager.UsageMode != LicenseUsageMode.Designtime)
    {
        //The control is not in design mode, add the column here.
    }
    
  2. 关于第二个解决方案,例如,添加一个新的 MyCustomImageColumn 类型就足够了,并且只检查是否存在 MyCustomImageColumn 类型的列,如果它存在,不要再添加一个,因为其中一个就足够了。

  3. 关于第三个解决方案。至少目前虽然您可以使用之前的两种简单解决方案,但我不建议您遵循它。因为 DataGridView 有自己的设计器名称 DataGridViewDesigner 是内部的,你不能继承它,如果你因为这个要求只创建一个设计器,你会错过原来的一些功能设计师。也许您可以解决这个问题,甚至可以创建 ToolBoxItem 而不是设计器,但您并不需要它。此处的选项是为了使答案更完整,对 future 的此类案例读者更有用。

关于c# - 在 Designer 中使用时自定义 DataGridView 列重复,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36501813/

相关文章:

c# - 泛型类型的隐式运算符

c# - 将 AAC 转换为 WAV

c# - 将多个 UserControl 附加到 WinForm 面板

c# - 将二进制文件字节数组发送到 web api 方法

javascript - 尝试将 $UI 元素附加到 <div> 标记时,如果没有错误输出,JQuery 将无法工作

单条 | C# 实例运算符和双杆 ||操作符的使用会影响代码

c# - 遍历树初始化变量

c# - 使用 NLog 从 Hangfire 计划的后台作业记录日志

c# - 如何使用注册表项将 VSTO 加载项添加到包含列表?

c# - 在 DAL 层使用 appsettings