Могу ли я иметь тип «класс» в C #?

Мне интересно, можно ли что-то сделать. У меня есть функция, которая читает файл XML и добавляет элементы управления в форму на основе содержимого файла. Узел xml, подобный этому, создаст его:

<Button Top="300" Left="100">Automatic</Button>

У меня есть функция, которая сохраняет элементы управления обратно в файл xml, если я добавил их в режиме редактирования. Это работает, но мне интересно, есть ли более простой способ. В настоящее время у меня есть код, который выглядит следующим образом для создания экземпляра каждого элемента управления:

            switch (xmlchild.Name)
            {
                // Create a new control whose type is specified.
                case "Button":
                    c = new Button();
                    break;
                case "Label":
                    c = new Label();
                    break;
                default:
                    c = null;
                    break;
            }

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

Спасибо!

10
задан Anthony Pegram 29 June 2010 в 15:05
поделиться

5 ответов

Если вы контролируете содержимое XML-файла, то да. Вы можете использовать:

string fullNameSpace = "System.Windows.Controls.";
Type controlType = Type.GetType( fullNameSpace + xmlchild.Name );
if( controlType != null )
{
  // get default constructor...
  ConstructorInfo ctor = controlType.GetConstructor(Type.EmptyTypes);
  object control = ctor.Invoke(null);
}

Вы также можете использовать класс Activator , чтобы немного очистить это:

object control = Activator.CreateInstance( "System.Windows.Presentation", 
                                           xmlchild.Name );

В качестве альтернативы, если вы можете создать действительный файл XAML, вы можете использовать XamlReader для восстановления дерева управления .

2
ответ дан 4 December 2019 в 03:15
поделиться

См. В первую очередь класс Activator. Затем вы можете сохранить имя типа элемента управления в качестве атрибута в XML-файле и использовать класс Activator для создания экземпляров на основе значения, хранящегося в атрибуте из текущего элемента xml (type = "fullTypeName").

Кроме того, если дело доходит до свойств, вы можете рассмотреть возможность отражения, чтобы установить свойства для созданных экземпляров на основе имени атрибута (т. Е. У вас есть экземпляр элемента управления, созданный с помощью класса Activator, и вы назначаете значение из атрибута Top в xml к свойству Top созданного экземпляра, которое вы можете получить / установить с помощью отражения).

1
ответ дан 4 December 2019 в 03:15
поделиться

Можно использовать Reflection, как другие описывали для построения управление прямо из его названия. Однако такая конструкция является довольно хрупкой и может также создавать проблемы безопасности, если XML-файл является общедоступным, поскольку произвольные типы элементов управления могут быть созданы во время выполнения на основе текста в файле. Это может не быть проблемой для вашего конкретного приложения.

Я бы предпочел дизайн с использованием Dictionary > , где у вас есть код, который регистрирует обратный вызов, который создает элемент управления для каждого имени. Это дает вам некоторую дополнительную гибкость (вы можете динамически менять методы построения элементов управления или комбинировать доступные элементы управления из нескольких источников), а также может выглядеть более чистым (переключатель заменяется несколькими вызовами `` регистр '', а фактическая конструкция разбита на отдельные методы или (в простом случае) как лямбда-выражение). Это также обеспечивает обратную совместимость, если вы заменяете TextBox в своем приложении MyImprovedTextBox и хотите, чтобы предыдущие файлы конфигурации использовали улучшенную версию.

1
ответ дан 4 December 2019 в 03:15
поделиться

Похоже, вы ищете что-то вроде Generics.

Вы можете сделать следующее:

public static class ControlFactory
{
    public static T CreateControl<T>() where T : Type, new()
    {
        return new T();
    }
}

Я еще не тестировал этот код, поэтому буду обновлять его по мере тестирования.

1
ответ дан 4 December 2019 в 03:15
поделиться

Вы можете использовать некоторые соглашения, чтобы сэкономить себе немного кода. В основном, используйте отражение для создания экземпляра любого элемента управления, который вы хотите, передавая код из XML. Что-то вроде:

Activator.CreateInstance(xmlchild.Name, ...)

Просто заполните нужные биты, и большая часть кода исчезнет.

1
ответ дан 4 December 2019 в 03:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: