是否可以为给定类的所有属性设置属性DesignerSerializationVisibility
的默认值?
在实践中,这是一种通过白名单方法将属性列入黑名单的默认行为的方法。
谢谢
最佳答案
我的偏爱
您可以在构造函数中为属性提供默认值,并使用适当的DefaultValue
属性装饰它们,然后设计器仅在它们的值与默认值不同时才会序列化它们。
同样,如果需要在设计时使它们不可见,则可以简单地使用Browsable(false)
装饰它们,那么它们将不会在设计时显示。
您也可以在属性设置器中检查DesignMode
,以防止在设计时为属性设置值,并使其成为运行时属性。
我还回答了您的问题,您需要不对没有DesignerSerializationVisibility属性的属性进行序列化。
至少该方法将为您介绍一个非常有用的功能
将来可能会对您有所帮助。
不序列化不具有DesignerSerializationVisibility属性的属性
切换将属性列入黑名单的默认行为的方法
使用白名单方法。
作为一种选择,您可以为组件创建一个自定义类型描述符,并使用它返回的自定义属性描述符,告诉设计人员不要序列化没有DesignerSerializationVisibility
的属性。
这样,当您希望设计人员序列化属性时,应使用DesignerSerializationVisibility
属性(以visible
作为值)修饰它。
象征
设计器要求属性的PropertyDescriptor
决定序列化该属性。如果描述符的ShouldSerialize
方法返回true
,它将对属性进行序列化,否则将不对属性进行序列化。
若要更改此行为,您应该重写该方法。为了使设计人员能够使用您的属性描述符,您应该为您的类注册一个自定义TypeDescriptionProvider
。提供者应为您的课程提供自定义TypeDescriptor
。自定义类型描述符应返回新的PropertyDescriptor
的列表,您可以覆盖该方法。
重要说明:要测试实现,应重新启动Visual Studio。
TypeDescriptionProvider
在这里,我们为组件创建一个自定义类型描述提供程序。然后,我们将为我们的组件注册提供者。
public class MyTypeDescriptionProvider : TypeDescriptionProvider
{
public MyTypeDescriptionProvider()
: base(TypeDescriptor.GetProvider(typeof(object))) { }
public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType,
object instance)
{
ICustomTypeDescriptor baseDescriptor = base.GetTypeDescriptor(objectType, instance);
return new MyTypeDescriptor(baseDescriptor);
}
}
类型描述符
在这里,我们实现了类型描述符,它的工作是返回自定义属性描述符的列表。
public class MyTypeDescriptor : CustomTypeDescriptor
{
ICustomTypeDescriptor original;
public MyTypeDescriptor(ICustomTypeDescriptor originalDescriptor)
: base(originalDescriptor)
{
original = originalDescriptor;
}
public override PropertyDescriptorCollection GetProperties()
{
return this.GetProperties(new Attribute[] { });
}
public override PropertyDescriptorCollection GetProperties(Attribute[] attributes)
{
var properties = base.GetProperties(attributes).Cast<PropertyDescriptor>()
.Select(p => new MyPropertyDescriptor(p))
.ToArray();
return new PropertyDescriptorCollection(properties);
}
}
属性描述符
这是我们的自定义属性描述符的实现。大多数属性和方法的实现都是微不足道的。仅对于
ShouldSerialize
方法,我们基于具有DesignerSerializationVisibility
public class MyPropertyDescriptor : PropertyDescriptor
{
PropertyDescriptor original;
public MyPropertyDescriptor(PropertyDescriptor originalProperty)
: base(originalProperty)
{
original = originalProperty;
}
// Implement other properties and methods simply using return original
// The implementation is trivial like this one:
// public override Type ComponentType
// {
// get { return original.ComponentType; }
// }
public override bool ShouldSerializeValue(object component)
{
if (original.Attributes.OfType<DesignerSerializationVisibilityAttribute>()
.Count() == 0)
return false;
return original.ShouldSerializeValue(component);
}
}
零件
最后是组件。如您在组件代码中看到的,我们装饰了一个要序列化的属性(白名单策略)。所有其他属性都不会序列化,因为这是我们附加到属性中的新行为。
[TypeDescriptionProvider(typeof(MyTypeDescriptionProvider))]
public class MyCustomClass : Component
{
public string Property1 { get; set; }
public string Property2 { get; set; }
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public string Property3 { get; set; }
}