将DesignerSerializationVisibility的默认值设置为hidden

时间:2016-03-31 15:08:33

标签: c# .net winforms visual-studio windows-forms-designer

有没有办法为给定类的所有属性设置属性DesignerSerializationVisibility的默认值?

实际上,这是一种使用 white-list 方法切换黑名单属性的默认行为的方法。

由于

1 个答案:

答案 0 :(得分:4)

我的优先选择

您可以在构造函数中为属性提供默认值,并使用合适的DefaultValue属性对其进行修饰,然后设计器只有在它们的值不同于默认值时才会对它们进行序列化。

此外,如果您需要在设计时使它们不可见,您可以使用Browsable(false)简单地装饰它们,然后它们将不会在设计时显示。

此外,您可以检查属性设置器中的DesignMode,以防止在设计时为属性设置值并使其成为运行时属性。

我也回答你需要的问题不序列化没有DesignerSerializationVisibility属性的属性。

  

至少这种方法会为您带来一个非常有用的功能   你可能会发现将来会有所帮助。

不序列化没有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; }
}