Отображение доступных строго типизированных классов ресурсов в окне свойств - PullRequest
2 голосов
/ 03 декабря 2008

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

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

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

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

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

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

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

Ответы [ 3 ]

1 голос
/ 05 декабря 2008

Я думаю, что нашел решение сейчас.

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

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

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

0 голосов
/ 07 декабря 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 сделает это для меня, хотя и более эффективно?

0 голосов
/ 05 декабря 2008

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...