Отображение доступных строго типизированных классов ресурсов в окне свойств

Я расширяю веб-элемент управления Gridview как свою первую попытку создания пользовательского элемента управления.

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

bool AutoLocalizeColumnHeaders — включает функцию

string HeaderResourceFile — определяет строго типизированный класс ресурсов, из которого можно получить текст заголовка.

Я переопределяю обработчик OnRowDataBound и получаю соответствующий ResourceManager, используя Reflection для заполнения текста заголовка. Все это работает хорошо, но я хотел бы отобразить список доступных строго типизированных классов ресурсов в окне свойств, чтобы пользователь мог выбирать, а не вводить имя вручную.

Я создал TypeConverter для отображения раскрывающегося списка, в котором отображаются доступные классы, но не могу понять, как получить список доступных имен классов для отображения?

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


person Graham Watson    schedule 03.12.2008    source источник


Ответы (3)


Думаю, теперь я нашел решение.

Выполнение следующего из события Page_Load дало мне имена классов ресурсов:

String[] resourceClassNames = (from type in assembly.GetTypes()
   where type.IsClass && type.Namespace.Equals("Resources")
   select type.Name).ToArray();

Поэтому я подумал, что смогу сделать что-то подобное внутри функции GetResourceFileNames (контекст ITypeDescriptorContext) преобразователя типов, используя параметр контекста, чтобы получить правильную сборку. К сожалению, мне удалось получить только сборку Custom Control или сборку System.Web.

Итак, вместо этого я создал UITypeEditor, в котором IServiceProvider передается в процедуру EditValue. Из этого я смог создать экземпляр ITypeDiscoveryService, который затем использовал для получения всех типов из правильной сборки:

public override object EditValue(ITypeDescriptorContext context, 
                                 IServiceProvider provider, object value)
{
    // Check if all the expected parameters are here
    if (context == null || context.Instance == null || provider == null)
    {
        // returning with the received value
        return base.EditValue(context, provider, value);
    }

    // Create the Discovery Service which will find all of the available classes
    ITypeDiscoveryService discoveryService = (ITypeDiscoveryService)provider.GetService(typeof(ITypeDiscoveryService));
    // This service will handle the DropDown functionality in the Property Grid
    _wfes = provider.GetService(typeof(IWindowsFormsEditorService)) as IWindowsFormsEditorService;

    // Create the DropDown control for displaying in the Properties Grid
    System.Windows.Forms.ListBox selectionControl = new System.Windows.Forms.ListBox();
    // Attach an eventhandler to close the list after an item has been selected
    selectionControl.SelectedIndexChanged += new EventHandler(selectionControl_SelectedIndexChanged);
    // Get all of the available types
    ICollection colTypes = discoveryService.GetTypes(typeof(object), true);
    // Enumerate the types and add the strongly typed
    // resource class names to the selectionControl
    foreach (Type t in colTypes)
    {
        if (t.IsClass && t.Namespace.Equals("Resources"))
        {
            selectionControl.Items.Add(t.Name);
        }
    }
    if (selectionControl.Items.Count == 0)
    {
        selectionControl.Items.Add("No Resources found");
    }
    // Display the UI editor combo
    _wfes.DropDownControl(selectionControl);

    // Return the new property value from the UI editor combo
    if (selectionControl.SelectedItem != null)
    {
        return selectionControl.SelectedItem.ToString();
    }
    else
    {
        return base.EditValue(context, provider, value);
    }
}

void selectionControl_SelectedIndexChanged(object sender, EventArgs e)
{
    _wfes.CloseDropDown();
}

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

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

person Graham Watson    schedule 05.12.2008

Интересная идея. Я полагаю, что ваше свойство в настоящее время установлено как строка? интересно, если вы установите свое свойство как Enum, а затем создадите Enum со строго типизированными классами ресурсов, будет ли он достаточно умен, чтобы показать их в окне свойств. он достаточно умен, чтобы показать его в коде позади, не понимаю, почему он не может загрузить его в окне свойств.

person Victor    schedule 05.12.2008

В моем решении, опубликованном ранее, я хотел найти способ сделать следующее с помощью LinQ:

    // Get all of the available types
    System.Collections.ICollection colTypes = discoveryService.GetTypes(typeof(object), true);
    // Enumerate the types and add the strongly typed resource class names to the selectionControl
    foreach (Type t in colTypes)
    {
        if (t.IsClass && t.Namespace.Equals("Resources"))
        {
            selectionControl.Items.Add(t.Name);
        }
    }

Кажется, это делает дело:

    // Get all of the available class names from the Resources namespace
    var resourceClassNames = from Type t in discoveryService.GetTypes(typeof(object), true)
                        where t.IsClass && t.Namespace.Equals("Resources")
                        select t.Name;

    selectionControl.Items.AddRange(resourceClassNames.ToArray());

Это, безусловно, выглядит намного чище, и я бы предположил, что он работает лучше, поскольку он не перебирает все доступные типы, проверяя те, которые соответствуют критериям в моем коде; хотя я полагаю, что LinQ сделает это за меня, хотя и более эффективным способом?

person Graham Watson    schedule 07.12.2008