Диалоговое окно динамических параметров (с использованием отражения) - PullRequest
2 голосов
/ 10 октября 2009

Кто-нибудь знает о хорошем компоненте (C # WinForms), который позволял бы создавать форму параметров (настроек), учитывая пользовательский класс с кучей свойств? Я не ищу что-то блестящее, но что-то просто лучше, чем сетка свойств. Я легко могу позаботиться о визуальной части, но я просто не хочу терять время на размышления о добавлении и связывании элементов управления, если они уже существуют.

Я почти уверен, что где-то раньше видел форму, подобную параметрам Visual Studio, которая была создана динамически (с некоторыми атрибутами, прикрепленными к свойствам класса, чтобы разрешить группировку и дополнительную информацию).

[Изменить] Например, у меня может быть класс параметров:

public class Options : SerializableOptions<Options>
{
     [Category("General")]
     [Name("User name")]
     [Description("Some text")]
     public string Username { get; set; }

     [Category("General")]
     [Name("Log in automatically")]
     public bool LogInAutomatically { get; set; }

     [Category("Advanced")]
     // ConnectionType is enum
     public ConnectionType ConnectionType { get; set; }

     // ...
}

После передачи его в эту форму будут созданы две панели («Общая» и «Расширенная») с CheckBox и TextBox на первой панели и один ComboBox (со всеми доступными перечислениями) на второй панели.

Если такого контроля нет, что вы, ребята, используете? Добавить, заполнить, отформатировать и связать элементы управления вручную для каждого параметра?

Ответы [ 3 ]

2 голосов
/ 10 октября 2009

Мне не известны какие-либо элементы управления, которые позволяют вам это делать, но это не сложно сделать самостоятельно. Самый простой способ - создать диалоговую оболочку, пользовательский элемент управления, который выступает в качестве базового класса для опций «панелей», один (или более) атрибут для управления именем и информацией о группировке, а также интерфейс (который реализует пользовательский элемент управления) .

Каждая из ваших пользовательских панелей параметров основана на пользовательском элементе управления и переопределяет какой-либо метод Initialize() и Save() (предоставляется пользовательским элементом управления). Он также предоставляет ваш атрибут (или атрибуты), которые определяют имя / информацию о группировке.

В диалоговой оболочке осмотрительно осмотрите все открытые типы из вашей сборки (или всех загруженных сборок) в поисках типов, реализующих ваш интерфейс. Когда вы найдете тип, получите атрибуты, чтобы определить, где разместить его в вашей группе (проще всего здесь использовать древовидное представление), вызвать Activator.CreateInstance, чтобы создать экземпляр пользовательского элемента управления и сохранить его в Tag имущество. Когда пользователь нажимает на запись в группе (узел дерева), получите Tag и установите панель, которая содержит пользовательский элемент управления, для объекта в свойстве Tag. Наконец, когда пользователь нажимает «ОК» в диалоговом окне, перебирает узлы дерева, получает свойство Tag и вызывает метод Save.

Обновление: Другой вариант - использовать элемент управления сеткой свойств. У него нет «симпатичного» интерфейса, но он очень функциональный, уже поддерживает группирование по атрибуту категории и обеспечивает большую гибкость. Вы можете использовать единую сетку свойств, которая показывает все параметры, или использовать «гибридный» подход с древовидным представлением, которое группирует по основным функциям (плагин, возможности и т. Д.), Вероятно, в зависимости от типа. Когда пользователь щелкает этот узел, присвойте сетке свойств экземпляр объекта. Единственным недостатком этого подхода является то, что при внесении изменений в значения сетки свойств они являются «живыми», поскольку базовое свойство немедленно изменяется, что означает отсутствие концепции «Отмена», за исключением сохранения копии каждого значения, которое может изменить и выполнить какой-то тип «перезагрузки» самостоятельно.

1 голос
/ 09 сентября 2010

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

Вот простой пример: http://blog.denouter.net/2008/08/simple-reflection-form.html. Он использует отражение для создания нескольких элементов управления на основе свойств объекта.

1 голос
/ 10 октября 2009

Я не знаю, существует ли такой элемент управления, но написание необходимого кода отражения действительно не так сложно. Например. как то так:

// the class for which to create an UI
public class MyClass
{
    public string Text { get; set; }
    public int ID { get; set; }
}

...

// basic reflection code to build the UI for an object
var obj = new MyClass() { Text="some text", ID=3};

foreach (var pi in obj.GetType().GetProperties())
{
    var name = pi.Name;
    var type = pi.PropertyType;
    var value = pi.GetValue(obj, null);

    //now setup the UI control for this property and display the value
}
...