编程语言
首页 > 编程语言> > c#-在运行时更改PropertyGrid的描述和类别属性

c#-在运行时更改PropertyGrid的描述和类别属性

作者:互联网

我正在使用PropertyGrid的业务应用程序上.我的项目负责人要我在运行时本地化PropertyGrid中的文本.欢呼!!!讽刺

我已经尝试了很多天来对PropertyGrid进行本地化.但是我很难在运行时更改属性描述和类别.更改DisplayName可以正常工作.

我举了一个简单的例子来重现该问题:创建一个Windows Form应用程序,并从ToolBox中添加一个PropertyGrid和一个具有默认设置的Button.

这是我想在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 click方法); PropertyGrid仅更改了DisplayName属性.说明和类别属性不变.

我真的很想解决这个问题.请提出任何建议或解决方案?

注1:
我不希望有任何回应说这是不可能的,并且只能在设计时设置属性.那是不对的!来自CodeProject.com的article显示了如何在运行时本地化PropertyGrid并更改属性的示例.不幸的是,在为解决此问题所需的那些部分确定示例范围时,我遇到了问题.

笔记2:
我想避免使用资源文件.这是由于本地化位于不同的语言文件中.每个文件包含一堆索引,每个索引都有一个字符串值.所有索引和字符串值都加载到Dictionary对象中.要访问字符串,索引用于访问它.不幸的是,我大多数使用此解决方案.

最好的祝福,
/ Mc_Topaz

解决方法:

这是一篇关于Globalized-property-grid的好文章

您可以为Person提供许多资源文件,而不是property-grid会本地化.

这是三个步骤:

>从GlobalizedObject继承
>为具有相同名称的Person提供资源文件(例如,Person.zh-cn.resx)
>更改要显示的线头比例.

您可以尝试,祝您好运!

标签:propertygrid,c,net
来源: https://codeday.me/bug/20191121/2052738.html