Как получить имя объекта компонента, который не поддерживает свойство .Name

1

MenuItem и ColumnHeader не являются производными от Control. В полной структуре они имеют собственное свойство .Name, но в компактной структуре они этого не делают. В Visual Studio разработчик формы показывает (Name) и, конечно, я могу получить доступ к этому объекту, используя это имя в коде. Но как я могу получить это имя как строку во время выполнения? Возможно ли это как-то, может быть, методом расширения, который возвращает имя?

Предполагается, что я создаю мобильные приложения с несколькими языковыми окнами, и чтобы найти текст для всех элементов в форме, я использую имя элемента управления как идентификатор.

Вот кто-то с той же проблемой и его решением, но мне это не нравится из-за дополнительных усилий, чтобы вводить все имена во второй раз в коде (а также поддерживать их при изменениях), после того как они уже были введены визуально в конструкторе, Я должен был сделать это для многих существующих MenuItems и ColumnHeaders...

this.AddMenuToDictionary(this.menuItemOpen, "menuItemOpen");
this.AddMenuToDictionary(this.menuItemExit, "menuItemExit");

Если действительно нет лучшего решения, чем использование такого словаря, по крайней мере, я хотел бы заполнить его без жестко закодированных строк. Могу ли я сделать это во время инициализации формы с помощью отражения?

  • 0
    Я собирался дать вам то же решение. Почему тебе это не нравится? Это просто индексация ссылок .......
  • 0
    @ MatíasFidemraizer, я ответил редактированием :)
Показать ещё 4 комментария
Теги:
reflection
compact-framework

1 ответ

1
Лучший ответ

Если у вас есть доступ к форме, а не только к самому объекту MenuItem, легко:

foreach (FieldInfo fi in form.GetType().GetFields(
    BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly))
    if (fi.FieldType.Name == "MenuItem")
    {
        var mi = (MenuItem) fi.GetValue(form);
        mi.Text = Translate(fi.ReflectedType.Namespace,
            fi.ReflectedType.Name + '.' + fi.Name, fi.FieldType.Name, mi.Text);
    }

Любые улучшения приветствуются, прокомментируйте или создайте лучший ответ.

Это также можно было бы сделать более широко для всех элементов управления в форме или, возможно, только для компонентов, не полученных из Control. С отражением нам даже не нужно бросать определенный тип (например, выше), мы могли бы просто искать существование свойства Text и переводить его.

Но поскольку я хотел создать идентификатор, включая иерархию подменю, я решил вернуться к подходу Dictionary и рекурсивно перебрать элементы (короткий псевдокод):

Dictionary<Component, string> ComponentNames;

foreach (FieldInfo fi in form.GetType().GetFields(
    BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly))
    if (fi.FieldType.Name == "MenuItem" || fi.FieldType.Name == "ColumnHeader")
        ComponentNames.Add((Component) fi.GetValue(form), fi.Name);

void Recurse(Menu menu, string strIdentifier) {
    if (ComponentNames.TryGetValue(menu, out strName))
         Translate(strIdentifer += '.' + strName, ref strText);
    foreach (MenuItem mi in menu.MenuItems) Recurse(mi, strIdentifier);
  • 0
    Да, я люблю это :)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню