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

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

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

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

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

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

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

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
624
3

Ответы 3

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

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

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

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

Поэтому я подумал, что смогу сделать что-то подобное внутри функции GetResourceFileNames (ITypeDescriptorContext context) TypeConverter, используя параметр context, чтобы получить правильную сборку. К сожалению, я мог получить только сборку 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, который сделает это или, действительно, лучший способ выполнить все это, то это будет очень приветствоваться.

В моем решении, опубликованном ранее, я хотел найти способ сделать следующее с помощью 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 сделает это за меня, хотя и более эффективным способом?

Другие вопросы по теме

Создание расширенного повторителя, удаление DataBind пользовательских добавленных элементов управления
Как получить контроль над таблицами стилей в темах ASP.NET с помощью элементов управления StylePlaceHolder и Style
Конфликт пользовательского серверного элемента управления ASP.NET (GridView), привязки данных и жизненного цикла элемента управления
Пользовательские элементы управления ASP.NET
Пользовательское текстовое поле со встроенным валидатором: проверка на стороне сервера не запускается
ASP.NET вводит javascript в пользовательский элемент управления, вложенный в панель обновлений
Элемент управления ASP.NET Treeview с поддержкой перетаскивания?
Как создать настраиваемый элемент управления ASP.NET с тире в имени?
Визуализировать самозакрывающийся тег в настраиваемом элементе управления ASP.NET, производном от Control
JQuery - Ajax - Как загрузить ascx в DIV, когда пользователь изменяет выбранный индекс в DropDownList