我有一个用户控件(A),其中包含一些其他控件(X,Y,Z)和我想隐藏用户控件的默认属性( A)如果在任何表单上使用用户控件(A),Visual Studio设计器中的属性工具框 。 经过一些研究后我发现我的用户控件需要一个自定义设计器,并且在该自定义设计器中,默认属性的 typedescriptor 将被更改,以便该属性拥有 BrowsableAttribute 价值假。
到目前为止,这对于大多数属性都很好。但如果我想隐藏 Dock-Property ,visual studio会向我显示未处理的异常。 我可以单击窗体中的控件(A)或(B,C,D)但是明显的第一件事是每个控件周围的虚线边框丢失,如果我想拖动控件,这个抛出异常:
如果我手动覆盖我的用户控件中的 Dock-Property ,设置 BrowsableAttribute 为false, 不会抛出异常。 我不知道为什么会发生这种情况以及如何控制这种行为。我也无法在网上找到任何东西。
有人可以解释那里发生了什么以及如何管理这个问题?
我附加了一个小型演示项目,没有任何特殊的附加参考。
Download Solution from OneDrive
控制A
[Designer(typeof(CustomControlDesigner))]
public partial class ControlA : UserControl
{
public ControlA()
{
SuspendLayout();
//
// ControlA
//
AutoScaleDimensions = new SizeF(6F, 13F);
AutoScaleMode = AutoScaleMode.Font;
BackColor = Color.Red;
Name = "ControlA";
ResumeLayout(false);
}
private IContainer components = null;
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
}
自定义设计器
public class CustomControlDesigner : ControlDesigner
{
protected override void PreFilterProperties(IDictionary properties)
{
var propertiesToHide = new []
{
"Tag",
"Dock"
};
foreach (string propname in propertiesToHide)
{
var prop = (PropertyDescriptor)properties[propname];
if (prop != null)
{
AttributeCollection runtimeAttributes = prop.Attributes;
Attribute[] attrs = new Attribute[runtimeAttributes.Count + 1];
runtimeAttributes.CopyTo(attrs, 0);
attrs[runtimeAttributes.Count] = new BrowsableAttribute(false);
prop = System.ComponentModel.TypeDescriptor.CreateProperty(GetType(), propname, prop.PropertyType, attrs);
properties[propname] = prop;
}
}
base.PreFilterProperties(properties);
}
}
表格
public partial class Form1 : Form
{
public Form1()
{
controlA1 = new ControlA();
SuspendLayout();
//
// controlA1
//
controlA1.Location = new Point(81, 81);
controlA1.Name = "controlA1";
controlA1.Size = new Size(150, 150);
controlA1.TabIndex = 1;
//
// Form1
//
AutoScaleDimensions = new SizeF(6F, 13F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(284, 261);
Controls.Add(controlA1);
Name = "Form1";
Text = "Form1";
ResumeLayout(false);
}
private IContainer components = null;
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
private ControlA controlA1;
}