c# - 设计器不序列化 UserControl 的 DataGridView 属性的列
问题描述
我正在尝试创建一个包含标签、工具条和 Datagridview 的自定义控件。
当测试表单生成设计代码时,它会正确保存工具条项目,但不会保存 Datagridview 列。 代码 DGrid.cs
...
[DesignerAttribute(typeof(MultiDesigner))]
public partial class FDGrid : Panel
{
....
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
[Category("Bars"), Description("Barra dei comandi.")]
public ToolStrip Barra
{
get { return _barra; }
set { _barra = value; }
}
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
[Category("Grid"), Description("Griglia dati.")]
public DataGridView Griglia
{
get { return _griglia; }
set { _griglia = value; }
}
....
}
[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name =
"FullTrust")]
public class MultiDesigner : System.Windows.Forms.Design.ControlDesigner
{
public override void Initialize(IComponent c)
{
base.Initialize(c);
FDGrid ctl = (FDGrid)c;
EnableDesignMode(ctl.Griglia, "Griglia");
EnableDesignMode(ctl.Barra, "Barra");
}
}
...
代码 FDGrid.Designer.cs
FDGrid.Designer.cs ....
private FDLabeledImage _titolo;
private ToolStrip _barra;
private DataGridView _griglia;
private void InitializeComponent()
{
this._barra = new System.Windows.Forms.ToolStrip();
this._griglia = new System.Windows.Forms.DataGridView();
this._titolo = new FDControl.FDLabeledImage();
((System.ComponentModel.ISupportInitialize)(this._griglia)).BeginInit();
this.SuspendLayout();
....
((System.ComponentModel.ISupportInitialize)(this._griglia)).EndInit();
this.ResumeLayout(false);
}
……
代码Form1.Designer.cs
....
private void InitializeComponent()
{
this.fdGrid1 = new FDControl.FDGrid(); // OK
this.fdGrid1.Column1 = new System.Windows.Forms.DataGridViewTextBoxColumn(); **// Error**
this.toolStripLabel1 = new System.Windows.Forms.ToolStripLabel(); //OK
}
...
private FDControl.FDGrid fdGrid1; //OK
private System.Windows.Forms.ToolStripLabel toolStripLabel1; //OK
private System.Windows.Forms.DataGridViewTextBoxColumnfdGrid1.Column1;//Error
...
帮助,我想了解我错在哪里?
解决方案
不是最优雅的,而是一个可行的解决方案:
创建一个
MyDataGridView
派生自的自定义DataGridView
:using System; using System.ComponentModel; using System.ComponentModel.Design; using System.Drawing.Design; using System.Reflection; using System.Windows.Forms; using System.Windows.Forms.Design; public class MyDataGridView : DataGridView { [Editor(typeof(ExtendedDataGridViewColumnCollectionEditor), typeof(UITypeEditor))] public new DataGridViewColumnCollection Columns { get => base.Columns; } private class ExtendedDataGridViewColumnCollectionEditor : UITypeEditor { private Form dataGridViewColumnCollectionDialog; private ExtendedDataGridViewColumnCollectionEditor() { } private static Form CreateColumnCollectionDialog(IServiceProvider provider) { var assembly = Assembly.Load(typeof(ControlDesigner).Assembly.ToString()); var type = assembly.GetType("System.Windows.Forms.Design.DataGridViewColumnCollectionDialog"); var ctor = type.GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance)[0]; return (Form)ctor.Invoke(new object[] { provider }); } public static void SetLiveDataGridView(Form form, DataGridView dgv) { var method = form.GetType().GetMethod("SetLiveDataGridView", BindingFlags.NonPublic | BindingFlags.Instance); method.Invoke(form, new object[] { dgv }); } public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value) { if (provider != null && context != null) { var service = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService)); if (service == null || context.Instance == null) return value; var host = (IDesignerHost)provider.GetService(typeof(IDesignerHost)); if (host == null) return value; if (dataGridViewColumnCollectionDialog == null) dataGridViewColumnCollectionDialog = CreateColumnCollectionDialog(provider); var dgv = ((MyDataGridView)context.Instance); var oldSite = dgv.Site; dgv.Site = ((MyDataGridView)context.Instance).Parent?.Site; SetLiveDataGridView(dataGridViewColumnCollectionDialog, dgv); using (var transaction = host.CreateTransaction("DataGridViewColumnCollectionTransaction")) { if (service.ShowDialog(dataGridViewColumnCollectionDialog) == DialogResult.OK) transaction.Commit(); else transaction.Cancel(); } dgv.Site = oldSite; } return value; } public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context) { return UITypeEditorEditStyle.Modal; } } }
构建解决方案。
创建您的
UserControl
并在其上放置一个实例MyDataGridView
。暴露
DataGridView
属性:public partial class MyUserControl : UserControl { public MyUserControl() { InitializeComponent(); } [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] public DataGridView DataGridView { get => dataGridView1; } }
构建解决方案。
在表单上放置一个实例
MyUserControl
,然后在属性编辑器窗口中,找到DataGridView
属性,展开它并编辑Columns
并保存表单。
这些列现在已序列化。你去吧。
注意:自定义UITypeEditor
基于此帖子,并进行了一些更改。
结果如下所示:
private void InitializeComponent()
{
...
...
this.Column1 = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.Column2 = new System.Windows.Forms.DataGridViewTextBoxColumn();
((System.ComponentModel.ISupportInitialize)(this.myUserControl1.DataGridView)).BeginInit();
this.SuspendLayout();
//
// myUserControl1
//
//
//
//
this.myUserControl1.DataGridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.myUserControl1.DataGridView.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
this.Column1,
this.Column2});
...
...
//
// Column1
//
this.Column1.HeaderText = "Column1";
this.Column1.MinimumWidth = 6;
this.Column1.Name = "Column1";
this.Column1.Width = 125;
//
// Column2
//
this.Column2.HeaderText = "Column2";
this.Column2.MinimumWidth = 6;
this.Column2.Name = "Column2";
this.Column2.Width = 125;
...
...
((System.ComponentModel.ISupportInitialize)(this.myUserControl1.DataGridView)).EndInit();
this.ResumeLayout(false);
}
...
private System.Windows.Forms.DataGridViewTextBoxColumn Column1;
private System.Windows.Forms.DataGridViewTextBoxColumn Column2;
...
推荐阅读
- xml - 如何从 SAP Ui5 中的 XML 文件中读取 HTML 输入字段?
- c - 标题和静态函数
- python-3.x - 在没有互联网的情况下安装 tensorflow
- boxplot - 在表示 R 中的置信区间的两点之间创建图
- amazon-web-services - 如何使用 hdockerpy 和 aws ecr repo 修复没有基本身份验证凭据错误?
- php - httpd.conf 中可能有语法错误
- python - 在 sagemaker 上的 tensorflow 上接收错误作为输入必须是一个向量,得到形状:[1,2]
- excel - VBA 在 Microsoft Word 中工作正常,但在 Libre Office 作家中无法工作如何修复
- c++ - 运行时动态函数解析
- c# - 无法从字符串转换为 Microsft.AspNetCore.Http.IFormFile