将DesignerSerializationVisibility的默认值设置为hidden
有没有办法为给定类的所有属性设置属性DesignerSerializationVisibility
的默认值?
实际上,这是一种使用白名单方法切换黑名单属性的默认行为的方法。
谢谢
我的偏见
您可以在构造函数中为属性提供默认值,并使用合适的DefaultValue
属性对它们进行装饰,然后设计器仅在它们的值不同于默认值时才序列化它们。
此外,如果您需要在设计时使它们不可见,您可以使用Browsable(false)
简单地装饰它们,然后它们将不会在设计时显示。
您还可以在属性设置器中检查DesignMode
,以防止在设计时为属性设置值并使其成为运行时属性。
我还回答了您需要的问题,而不是序列化没有DesignerSerializationVisibility属性的属性 。
至少这种方法会为您介绍一个非常有用的function,您可能会发现它有用。
不序列化没有DesignerSerializationVisibility属性的属性
一种使用白名单方法切换将属性列入黑名单的默认行为的方法。
作为选项,您可以为组件创建自定义类型描述符并使用它返回的自定义属性描述符,告诉设计者不要序列化没有DesignerSerializationVisibility
属性。
这样,当您希望设计器序列化属性时,您应该使用带有visible
值的DesignerSerializationVisibility
属性来装饰它。
Implemetaion
设计者要求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); } }
TypeDescriptor
这里我们实现了我们的类型描述符,它的工作是返回我们的自定义属性描述符列表。
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() .Select(p => new MyPropertyDescriptor(p)) .ToArray(); return new PropertyDescriptorCollection(properties); } }
的PropertyDescriptor
这是我们的自定义属性描述符的实现。 大多数属性和方法的实现都是微不足道的。 仅对于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() .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; } }