DataGridView AutoGenerateColumns以某种方式设置为true

我从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”。

有任何想法吗?

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

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

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

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

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

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

不幸的是,这是预料之中的。 因为您将AutogenerateColumns声明为new ,所以对它的调用不会被虚拟化。 当父代码将AutogenerateColumns设置为true ,它不会传递到属性设置器中。 虽然这不会对行为产生任何直接影响(因为你不做任何事情而是遵从父属性),但它确实限制了你的调试能力,因为你不能做一个Console.WriteLine(Environment.StackTrace)或者你的二传手中类似的东西。

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

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

我的解决方案很简单:通过覆盖OnAutoGenerateColumnsChanged监视AutoGenerateColumns的更改,如果不需要则还原更改:

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

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