DesignerSerializationVisibility

DesignerSerializationVisibility

是否可以为给定类的所有属性设置属性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; }
}

10-06 13:29