有没有办法为给定类的所有属性设置属性DesignerSerializationVisibility
的默认值?
实际上,这是一种使用 white-list 方法切换黑名单属性的默认行为的方法。
由于
答案 0 :(得分:4)
您可以在构造函数中为属性提供默认值,并使用合适的DefaultValue
属性对其进行修饰,然后设计器只有在它们的值不同于默认值时才会对它们进行序列化。
此外,如果您需要在设计时使它们不可见,您可以使用Browsable(false)
简单地装饰它们,然后它们将不会在设计时显示。
此外,您可以检查属性设置器中的DesignMode
,以防止在设计时为属性设置值并使其成为运行时属性。
我也回答你需要的问题不序列化没有DesignerSerializationVisibility属性的属性。
至少这种方法会为您带来一个非常有用的功能 你可能会发现将来会有所帮助。
一种切换黑名单属性的默认行为的方法 用白名单方法。
作为一个选项,您可以为组件创建自定义类型描述符,并使用它返回的自定义属性描述符,告诉设计者不要序列化没有DesignerSerializationVisibility
的属性。 / p>
这样,当您希望设计器序列化某个属性时,您应该使用DesignerSerializationVisibility
属性来装饰它,并将visible
作为值。
<强> 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<PropertyDescriptor>()
.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<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; }
}