c# - 在运行时更改 PropertyGrid Description 和 Category 属性

标签 c# .net propertygrid

我正在开发一个使用 PropertyGrid 的业务应用程序。我的项目负责人希望我在运行时本地化 PropertyGrid 中的文本。欢呼!!! 讽刺

我已经尝试了很多天来本地化 PropertyGrid。但是我在运行时更改属性 DescriptionCategory 时遇到了麻烦。更改 DisplayName 效果很好。

我做了一个简单的例子来重现这个问题:创建一个 Windows 窗体应用程序 并从 ToolBox 添加一个 PropertyGrid 和一个 <具有默认设置的 strong>按钮。

这是我想在 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)成员。

    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 对象(DescriptionAttributeCategoryAttribute) 有一个成员发生了变化。

运行这三个方法并重置PropertyGrid后(见button1点击方法); PropertyGrid 仅更改了 DisplayName 属性DescriptionCategory 属性未更改。

我真的很想得到一些帮助来解决这个问题。请任何建议或解决方案?

注1: 我不希望任何回复说这是不可能的,属性只能在设计时设置。那不是真的!这article来自 CodeProject.com 的示例展示了如何本地化 PropertyGrid 并在运行时更改属性。不幸的是,我无法确定我需要解决此问题的那些部分的示例范围。

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

最好的问候, /Mc_Topaz

最佳答案

这里是的好文章Globalized-property-grid

您可以为 Person 提供许多资源文件,propery-grid 将本地化。

这里是三步:

  1. 继承自 GlobalizedObject
  2. 给出Person的同名资源文件(eg.Person.zh-cn.resx)
  3. 更改要显示的话题的风格。

你可以试试,祝你好运!

关于c# - 在运行时更改 PropertyGrid Description 和 Category 属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24468820/

相关文章:

c# -++后缀和前缀的由来

c# - ASP.net MVC - 每个 View 或每个操作一个 ViewModel?

c# - 一系列调用中的C#错误处理

c# - If 语句评估为 false 但仍然分支,就好像它是 true

.net - Azure:用户登录失败

c# - PropertyGrid 中 boolean 属性的自定义编辑器 (C#)

.net - 当 Visual Studio 编译已经启动时,我可以停止它吗?

.net - CompileAssemblyFromSource 生成的程序集异常没有行号

c# - 具有空和非空类别的 WinForms PropertyGrid

.net - 在设计 View 属性网格中禁用属性