我想知道如何在运行时更改DisplayNameAttribute,当我进行一些转换时,我希望displayName在我的属性网格中是Feet而不是Meters,这可能吗?
[DisplayName("Meters")]
public double Distance
{
get{return distance;}
}
Run Code Online (Sandbox Code Playgroud)
Mar*_*ell 12
有许多不同的方法可以做到这一点.最简单的是做一些类似于某些i18n产品的做法 - 将属性子类化并截取文本; 但这仅在您拥有类型时才有效,并且从属性中您无法访问上下文.
接下来要看的是TypeConverter,因为它提供了对属性的组件模型视图的访问,并且比下两个选项更简单;-p这将适用于PropertyGrid,但不是DataGridView等等.
列表中的下一个是ICustomTypeDescriptor- 不是一个有趣的实现接口,但您可以交换自己的属性描述符.这要求您拥有该类型(以提供接口支持).
最后,CustomTypeDescriptor就像最后一样,但即使对于你不拥有的类型也是如此,并允许在类型和对象级别访问调整的元数据(其他一切只支持对象).
选择哪个?我怀疑那TypeConverter是最明智的; 你需要对象上下文(子类属性不提供),但你不需要额外的复杂性.
这是一个例子; 请注意,在TypeConverter代码中我们可以访问对象上下文.如果名称很简单,那么将其放入TypeConverter(创建属性时)就足够了.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Forms;
class MyFunkyTypeConverter : ExpandableObjectConverter
{
public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)
{
PropertyDescriptorCollection props = base.GetProperties(context, value, attributes);
List<PropertyDescriptor> list = new List<PropertyDescriptor>(props.Count);
foreach (PropertyDescriptor prop in props)
{
switch (prop.Name)
{
case "Distance":
list.Add(new DisplayNamePropertyDescriptor(
prop, "your magic code here"));
break;
default:
list.Add(prop);
break;
}
}
return new PropertyDescriptorCollection(list.ToArray(), true);
}
}
class DisplayNamePropertyDescriptor : PropertyDescriptor
{
private readonly string displayName;
private readonly PropertyDescriptor parent;
public DisplayNamePropertyDescriptor(
PropertyDescriptor parent, string displayName) : base(parent)
{
this.displayName = displayName;
this.parent = parent;
}
public override string DisplayName
{get { return displayName; } }
public override bool ShouldSerializeValue(object component)
{ return parent.ShouldSerializeValue(component); }
public override void SetValue(object component, object value) {
parent.SetValue(component, value);
}
public override object GetValue(object component)
{
return parent.GetValue(component);
}
public override void ResetValue(object component)
{
parent.ResetValue(component);
}
public override bool CanResetValue(object component)
{
return parent.CanResetValue(component);
}
public override bool IsReadOnly
{
get { return parent.IsReadOnly; }
}
public override void AddValueChanged(object component, EventHandler handler)
{
parent.AddValueChanged(component, handler);
}
public override void RemoveValueChanged(object component, EventHandler handler)
{
parent.RemoveValueChanged(component, handler);
}
public override bool SupportsChangeEvents
{
get { return parent.SupportsChangeEvents; }
}
public override Type PropertyType
{
get { return parent.PropertyType; }
}
public override TypeConverter Converter
{
get { return parent.Converter; }
}
public override Type ComponentType
{
get { return parent.ComponentType; }
}
public override string Description
{
get { return parent.Description; }
}
public override PropertyDescriptorCollection GetChildProperties(object instance, Attribute[] filter)
{
return parent.GetChildProperties(instance, filter);
}
public override string Name
{
get { return parent.Name; }
}
}
[TypeConverter(typeof(MyFunkyTypeConverter))]
class MyFunkyType
{
public double Distance {get;set;}
public double AnotherProperty { get; set; }
}
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.Run(new Form { Controls = {
new PropertyGrid { Dock = DockStyle.Fill,
SelectedObject = new MyFunkyType {
Distance = 123.45
}}
}});
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11570 次 |
| 最近记录: |