【发布时间】:2014-08-19 13:36:30
【问题描述】:
我正在开发一个使用 PropertyGrid 的业务应用程序。我的项目负责人希望我在运行时本地化 PropertyGrid 中的文本。欢呼!!! 讽刺
我已经尝试了很多天来本地化 PropertyGrid。但我无法在运行时更改属性 Description 和 Category。更改 DisplayName 效果很好。
我做了一个简单的例子来重现这个问题:创建一个 Windows 窗体应用程序,并从 ToolBox 添加一个 PropertyGrid 和一个 按钮。
这是我想在 PropertyGrid 中显示的类:
class Person
{
int age;
public Person()
{
age = 10;
}
[Description("Person's age"), DisplayName("Age"), Category("Fact")]
public int Age
{
get { return age; }
}
}
在表单的构造函数中;我创建了 Person 对象并将其显示在 PropertyGrid 中。
public Form1()
{
InitializeComponent();
propertyGrid1.SelectedObject = new Person();
}
该按钮用于在运行时更改 DisplayName、Description 和 Category 属性。
private void button1_Click(object sender, EventArgs e)
{
SetDisplayName();
SetDescription();
SetCategory();
propertyGrid1.SelectedObject = propertyGrid1.SelectedObject; // Reset the PropertyGrid
}
SetDisplayName() 方法工作正常,实际上在运行时更改了属性的 DisplayName!
private void SetDisplayName()
{
Person person = propertyGrid1.SelectedObject as Person;
PropertyDescriptor descriptor = TypeDescriptor.GetProperties(person)["Age"];
DisplayNameAttribute attribute = descriptor.Attributes[typeof(DisplayNameAttribute)] as DisplayNameAttribute;
FieldInfo field = attribute.GetType().GetField("_displayName", BindingFlags.NonPublic | BindingFlags.Instance);
field.SetValue(attribute, "The age");
}
SetDescription() 和 SetCategory() 方法与 SetDisplayName() 方法几乎相同,除了一些类型更改和字符串访问每个属性的私有成员。
private void SetDescription()
{
Person person = propertyGrid1.SelectedObject as Person;
PropertyDescriptor descriptor = TypeDescriptor.GetProperties(person)["Age"];
DescriptionAttribute attribute = descriptor.Attributes[typeof(DescriptionAttribute)] as DescriptionAttribute;
FieldInfo field = attribute.GetType().GetField("description", BindingFlags.NonPublic |BindingFlags.Instance);
field.SetValue(attribute, "Age of the person");
}
private void SetCategory()
{
Person person = propertyGrid1.SelectedObject as Person;
PropertyDescriptor descriptor = TypeDescriptor.GetProperties(person)["Age"];
CategoryAttribute attribute = descriptor.Attributes[typeof(CategoryAttribute)] as CategoryAttribute;
FieldInfo[] fields = attribute.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance);
FieldInfo field = attribute.GetType().GetField("categoryValue", BindingFlags.NonPublic | BindingFlags.Instance);
field.SetValue(attribute, "Info");
}
SetDescription() 和 SetCategory() 方法都可以编译和运行,但不会影响 ProperytGrid。在每个方法的最后一行之后,您可以使用 IntelliSense 查看 Attribute 对象(DescriptionAttribute 和 CategoryAttribute) 有一个成员发生了变化。
运行这三个方法并重置PropertyGrid后(见button1点击方法); PropertyGrid 只更改了 DisplayName 属性。 Description 和 Category 属性不变。
我真的很想得到一些帮助来解决这个问题。请问有什么建议或解决办法吗?
注 1: 我不希望任何回应说这是不可能的,并且只能在设计时设置属性。那不是真的!这个来自 CodeProject.com 的article 展示了如何本地化 PropertyGrid 并在运行时更改属性的示例。不幸的是,我在为解决此问题所需的那些部分确定示例的范围时遇到问题。
注意 2: 我想避免使用资源文件。这是由于本地化位于不同的语言文件中。每个文件都包含一堆索引,每个索引都有一个字符串值。所有索引和字符串值都加载到 Dictionary 对象中。要访问字符串,使用索引来访问它。不幸的是,我最常使用此解决方案。
最好的问候, /Mc_Topaz
【问题讨论】:
标签: c# .net propertygrid