c# - 将 DesignerSerializationVisibility 的默认值设置为隐藏

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

有没有办法为给定类的所有属性设置 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/

相关文章:

c# - 失去焦点后如何保持 NumericUpDown 的无效值?

.net - Windows 窗体的 Awesomebar-like 行为

c# - 单击菜单条时禁用 'requirement' 以双击未聚焦的窗口

c# - 像这样的语法在 C# 中意味着什么?

c# - 使用 ViewModels 通过按钮将文本框绑定(bind)到文本 block

c# - DDD实体持久化场景

c# - 模拟流以读取字节[]

c# - Xamarin 项目在 Visual Studio 2015 中不可用

c# - Topshelf - 基于自定义参数启动线程

c# - GotFocus 上的 MaskedTextBox.SelectAll 不适用于鼠标