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