C# 设计师没有';UserControl的DataGridView属性的t serialzie列
我正在尝试创建一个自定义控件,它包含一个标签、一个toolstrip和一个Datagridview 当测试表单生成设计代码时,它会正确地保存toolstrip项,但不会保存Datagridview列。 代码DGrid.csC# 设计师没有';UserControl的DataGridView属性的t serialzie列,c#,.net,winforms,components,windows-forms-designer,C#,.net,Winforms,Components,Windows Forms Designer,我正在尝试创建一个自定义控件,它包含一个标签、一个toolstrip和一个Datagridview 当测试表单生成设计代码时,它会正确地保存toolstrip项,但不会保存Datagridview列。 代码DGrid.cs ... [DesignerAttribute(typeof(MultiDesigner))] public partial class FDGrid : Panel { .... [DesignerSerializati
...
[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");
}
}
...
....
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
...
代码FDGrid.Designer.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");
}
}
...
....
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
...
FDGrid.Designer.cs
代码格式1.Designer.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");
}
}
...
....
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
...
帮助,我想知道我错在哪里?不是最优雅的,而是一个有效的解决方案:
DataGridView
派生的自定义MyDataGridView
:
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
属性,展开它并编辑列
,然后保存表单
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;
...
根据测试,我删除了代码中不必要的部分。(定制ColumnCollection和重写CreateColumnCollectionDialog是不必要的。)现在它可能是最优雅的解决方案,感谢您的回复和您为我奉献的时间。在我的情况下,当我添加一个专栏并将其保存到应用程序和visualstudio中时,它不起作用。这个解决方案在VS 2019-.NET 4.8中进行了测试。我建议你从一个干净的项目开始,严格按照步骤进行。在您使它工作之后,您可以将它修改为您想要在控件中包含的任何内容。它很好用。谢谢