有没有办法为给定类的所有属性设置 DesignerSerializationVisibility
属性的默认值?
在实践中,一种方法可以将属性的黑名单默认行为切换为白名单方法。
谢谢
最佳答案
我的偏好
您可以在构造函数中为属性提供默认值并使用合适的 DefaultValue
修饰它们属性,那么只有当它们的值不同于默认值时,设计者才会将它们序列化。
此外,如果您需要在设计时使它们不可见,您可以使用 Browsable(false)
简单地装饰它们那么它们将不会在设计时显示。
你也可以查看DesignMode
在属性 setter 中防止在设计时为属性设置值并使其成为运行时属性。
我还回答了您的问题,您需要不序列化没有 DesignerSerializationVisibility 属性的属性。
At least the approach will introduce a really useful feature to you which you may find helpful in the future.
不序列化没有 DesignerSerializationVisibility 属性的属性
A way to switch the default behavior of blacklisting the properties with a white list approach.
作为一个选项,您可以为您的组件创建自定义类型描述符并使用它返回的自定义属性描述符,告诉设计者不要序列化没有 DesignerSerializationVisibility
的属性。 .
这样,当您希望设计器序列化一个属性时,您应该使用 DesignerSerializationVisibility
属性对其进行装饰,并将 visible
作为值。
实现
设计师问PropertyDescriptor
决定序列化该属性的属性。如果ShouldSerialize
描述符的方法返回 true
它序列化该属性,否则它不序列化该属性。
要更改此行为,您应该覆盖该方法。要让设计器使用您的属性描述符,您应该注册一个自定义 TypeDescriptionProvider
为你的类(class)。提供商应提供自定义 TypeDescriptor
为你的类(class)。自定义类型描述符应返回您覆盖该方法的新 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; }
}
关于c# - 将 DesignerSerializationVisibility 的默认值设置为隐藏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36337249/