DataGridView AutoGenerateColumns以某种方式设置为true

时间:2009-07-27 17:37:27

标签: c# .net winforms datagridview

我从DataGridView派生出DataGridViewEx类,如下所示:

public class DataGridViewEx : DataGridView
{
    // ... 

    [DefaultValue(false)]
    [Browsable(true)]
    public new bool AutoGenerateColumns
    {
        get { return base.AutoGenerateColumns; }
        set { base.AutoGenerateColumns = value; }
    }

    public DataGridViewEx()
    {
        AutoGenerateColumns = false;
    }

    // ...
}

但是,当我将DataGridViewEx控件添加到表单时,我看到AutoGenerateColumns属性设置为true!我的代码没有在任何地方将其设置为true,因此“其他人”:)将其设置为true。当然,上面列出的代码会执行,AutoGenerateColumns会暂时设置为false,但稍后会变为“true”。

有什么想法吗?

4 个答案:

答案 0 :(得分:4)

我下载了.NET源代码,以便能够调试.NET框架,如下所述:
http://referencesource.microsoft.com/serversetup.aspx

然后我在DataGridView.AutoGenerateColumns属性上放置一个断点,发现它在System.Windows.Forms.Design.DataGridViewDesigner.Initialize()方法中设置为true。
我在反射器中打开了这个方法并看到了以下内容:

public override void Initialize(IComponent component)  
{
  ...
  view.AutoGenerateColumns = view.DataSource == null;
  ...
}

因此,当DataSource为null时,Initialize()方法将AutoGeneratedColumns设置为true:(

我想从DataGridViewDesigner类派生我自己的设计器来覆盖此行为,但DataGridViewDesigner是内部的,所以我不能。

所以似乎没有办法正确解决这个问题:(

答案 1 :(得分:2)

不幸的是,这是预料之中的。由于您将AutogenerateColumns声明为new,因此对其的调用不会被虚拟化。当父代码将AutogenerateColumns设置为true时,它不会传递到您的属性设置器中。虽然这不会对行为产生任何直接影响(因为你不做任何事情而是遵从父属性),但 限制你的调试能力,因为你不能做{ {1}}或您的二传手中的类似内容。

您可能需要使用像Reflector这样的工具来尝试找到它设置为true的位置,但除了最简单的场景之外,这将是一个问题(例如,如果父级直接设置了支持变量) 。你真的需要做一些试验和错误来找到设置值的位置,然后调用你的Console.WriteLine(Environment.StackTrace)代码。我会覆盖AutoGeneratedColumns = false;并检查那里的值作为开始。

答案 2 :(得分:2)

这对我来说也是一个问题。由于某种原因,AutogenerateColumns属性具有[Browsable(false)]属性,因此它不会显示在设计器中。要解决此问题,我确保在包含DataGridView控件的窗体的构造函数中设置AutogenerateColumns = False。我相信,只要你在之前数据绑定,它应该按预期工作。

答案 3 :(得分:2)

我的解决方案非常简单:通过覆盖AutoGenerateColumns来关注OnAutoGenerateColumnsChanged的更改,如果不需要则还原更改:

public class MyDataGridView : DataGridView
{
    private bool mbAutoGenerateColumns = false;

    [Browsable(true)]
    [Category("Behavior")]
    [DefaultValue(false)]
    new public bool AutoGenerateColumns
    {
        get { return base.AutoGenerateColumns; }
        set { base.AutoGenerateColumns = mbAutoGenerateColumns = value; }
    }

    public MyDataGridView()
    {
        // Set AGC to false right on the start
        AutoGenerateColumns = false;
    }

    protected override void OnAutoGenerateColumnsChanged(EventArgs e)
    {
        base.OnAutoGenerateColumnsChanged(e);

        // When AGC gets changed, check if the change happened
        //  internally or through the new property.
        // If internally, revert!
        // Since DGV has a tendency to enable AGC, only the setting
        //  to false is explicitly needed, the rest happens automatically
        if(!mbAutoGenerateColumns && base.AutoGenerateColumns)
            base.AutoGenerateColumns = false;
    }
}

我知道这是一个非常黑客,但是它起作用,因为控制设计器 - 如前所述 - 是不可推导的,它是我能找到的最好的。