将多个属性合并为一个属性-合并属性

在控件上,我正在使用多个属性属性:

[Browsable(false)]

[Bindable(false)]

[EditorBrowsable(EditorBrowsableState.Never)]

[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]

[Obsolete("", true)]

public new Boolean AllowDrop;

我也在许多其他控件属性上使用这些属性。

我想知道是否有一种方法可以减少每次编写的代码量。

如果可以像这样组合多个属性,那就太好了:

[Hidden(true)]

public new Boolean AllowDrop;

Hidden属性将包括以上所有属性。因此,只有1行代码。

也许还有一种方法可以将属性组合到宏之类的东西中?

我知道还有其他隐藏属性的方法,但是我选择了使用属性的方法。

谢谢

回答:

这取决于使用该属性的框架。

组合属性对于使用和解释属性的上下文可能是有意义的。例如,对于那些使用.Net类型描述机制的上下文,您可以自定义.Net返回给使用者的类型描述。

为此,可以使用标准.Net机制为类型提供自定义元数据,并为对象注册自定义类型描述符。

通过为您的类型创建自定义类型描述符,该想法将以这种方式起作用。在自定义类型描述符中,您将为类型的属性返回自定义属性描述符,在属性描述符中,将为属性返回一组自定义属性。

该方法需要更多代码,但它确实很有趣,并且共享了一些有关如何为您的类型提供自定义元数据的好主意:

该用法提供了创建MetaDataAttributes的标准方法。实现此接口的每个属性都将用作元数据,并且将使用它在Process方法中返回的那些属性代替该属性:

public interface IMetadatAttribute

{

Attribute[] Process();

}

这是一个示例元数据属性,在处理属性时会返回一些属性:

public class MySampleMetadataAttribute : Attribute, IMetadatAttribute

{

public Attribute[] Process()

{

var attributes = new Attribute[]{

new BrowsableAttribute(false),

new EditorBrowsableAttribute(EditorBrowsableState.Never),

new BindableAttribute(false),

new DesignerSerializationVisibilityAttribute(

DesignerSerializationVisibility.Hidden),

new ObsoleteAttribute("", true)

};

return attributes;

}

}

此类将由自定义类型描述符使用,以提供该属性的自定义属性列表:

public class MyPropertyDescriptor : PropertyDescriptor

{

PropertyDescriptor original;

public MyPropertyDescriptor(PropertyDescriptor originalProperty)

: base(originalProperty) { original = originalProperty;}

public override AttributeCollection Attributes

{

get

{

var attributes = base.Attributes.Cast<Attribute>();

var result = new List<Attribute>();

foreach (var item in attributes)

{

if(item is IMetadatAttribute)

{

var attrs = ((IMetadatAttribute)item).Process();

if(attrs !=null )

{

foreach (var a in attrs)

result.Add(a);

}

}

else

result.Add(item);

}

return new AttributeCollection(result.ToArray());

}

}

// 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 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);

}

}

此类将在您的类型上方的属性中使用,以介绍我​​们创建的自定义类型描述符,作为该类型的元数据引擎:

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);

}

}

这是我的示例类,其Name属性使用其修饰,MySampleMetadataAttribute并且该类本身已注册为使用我们的自定义类型描述符提供程序:

[TypeDescriptionProvider(typeof(MyTypeDescriptionProvider))]

public class MySampleClass

{

public int Id { get; set; }

[MySampleMetadataAttribue]

[DisplayName("My Name")]

public string Name { get; set; }

}

要查看结果,足以创建该类的实例并在中查看结果PropertyGrid

var o = new MySampleClass();

this.propertyGrid1.SelectedObject = o;

  • 可能它不像您期望的那样简单。但它正在工作。
  • 这是一个冗长的答案,但包含一个完整的工作示例,说明如何将类型描述符应用于类型以提供自定义元数据。
  • 该方法不适用于使用反射而不是类型描述的引擎。但是它完全可以与例如PropertyGrid与类型描述一起使用的控件一起使用。

以上是 将多个属性合并为一个属性-合并属性 的全部内容, 来源链接: utcz.com/qa/416623.html

回到顶部