将 DesignerSerializationVisibility 的默认值设置为隐藏

Tes*_*esX 1 .net c# windows-forms-designer visual-studio winforms

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

在实践中,有一种方法可以使用白名单方法来切换将属性列入黑名单的默认行为。

谢谢

Rez*_*aei 8

我的偏好

您可以在构造函数中为属性提供默认值,并使用合适的DefaultValue属性来装饰它们,然后设计器仅当它们的值与默认值不同时才会序列化它们。

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

此外,您还可以签DesignMode入属性设置器,以防止在设计时设置属性值并将其设为运行时属性。

我还回答了您需要的问题Not Serialize没有 DesignerSerializationVisibility attribute 的属性

至少该方法将为您介绍一个真正有用的功能,您可能会发现它在将来很有帮助。

不序列化没有 DesignerSerializationVisibility 属性的属性

一种使用白名单方法切换将属性列入黑名单的默认行为的方法。

作为一个选项,您可以为组件创建自定义类型描述符,并使用它返回的自定义属性描述符,告诉设计者不要序列化不具有DesignerSerializationVisibility.

这样,当您希望设计器序列化属性时,您应该使用具有值的DesignerSerializationVisibility属性来装饰它visible

实施

设计者要求PropertyDescriptor属性决定序列化该属性。如果ShouldSerialize描述符的方法返回,true它将序列化该属性,否则它不会序列化该属性。

要更改此行为,您应该覆盖该方法。为了让设计者使用你的属性描述符,你应该TypeDescriptionProvider为你的类注册一个自定义。提供商应该TypeDescriptor为您的班级提供定制服务。自定义类型描述符应返回您重写该方法的新类型描述符的列表PropertyDescriptor

重要提示:要测试实现,您应该重新启动 Visual Studio。

类型描述提供者

在这里,我们为我们的组件创建一个自定义类型描述提供程序。然后我们将为我们的组件注册提供者。

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

类型描述符

在这里,我们实现了类型描述符,它的工作是返回自定义属性描述符的列表。

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

属性描述符

这是我们的自定义属性描述符的实现。大多数属性和方法的实现都很简单。仅对于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);
    }
}
Run Code Online (Sandbox Code Playgroud)

成分

最后是组件。正如您在组件代码中看到的,我们装饰了一个要序列化的属性(白名单策略)。所有其他属性都不会序列化,因为这是我们附加到属性的新行为。

[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; }
}
Run Code Online (Sandbox Code Playgroud)

  • 出于学习目的,您还可以覆盖“PropertyDescriptor”的“Attributes”属性,并检查该属性是否没有附加“DesignerSerializationVisibility”属性,然后将值为“DesignerSerializationVisibility.None”的属性实例添加到财产的属性。 (2认同)