PropertyGrid отображает текстовое поле, а не как раскрывающийся список

1

Этот вопрос (Как создать редактор PropertyGrid, который ограничивает строку символами n) почти делает именно то, что мне нужно, но вместо того, чтобы использовать раскрывающийся список, я хотел бы, чтобы редактирование произошло в самой сетке.

Изображение 174551

UITypeEditorEditStyle, похоже, не очень помогает, поскольку установка его в None полностью исключает элемент управления UITypeEditorEditStyle.

Или, есть ли более простой способ получить доступ к TextBox, который элемент управления использует, чтобы подключиться к событиям там?

В конечном счете, я ищу виджет ввода текста, который ограничивает длину ввода, который 1. сделал inline, и 2. не дожидаясь, пока пользователь перестанет печатать, чтобы дать им ошибку или усечь вход.

Теги:
user-interface
propertygrid

1 ответ

2
Лучший ответ

Вы можете использовать TypeConverter, который бы ограничивал текст после его ввода. Это будет работать только с текстовым полем. Предположим, что у меня есть этот класс, который я хочу редактировать, используя сетку свойств:

public class MyClass
{
    [TypeConverter(typeof(MyTypeConverter))]
    public string MyText { get; set; }
}

Вот код конвертера типов, который делает это:

public class MyTypeConverter : TypeConverter
{
    public const int MaxLength = 10;

    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
        return sourceType == typeof(string);
    }

    public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
    {
        return destinationType == typeof(string);
    }

    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
    {
        return Truncate(value as string, MaxLength);
    }

    public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
    {
        return Truncate(value as string, MaxLength);
    }

    private static string Truncate(string value, int maxLength)
    {
        if (value == null)
            return null;

        return value.Length <= maxLength ? value : value.Substring(0, maxLength);
    }
}

В противном случае вы можете взломать сетку, как я здесь демонстрирую. Это не UITypeEditor, потому что базовое текстовое поле используется для всех элементов. Следующий подход основан на событиях выбора. Опять же, это еще один класс, который я хочу изменить:

public class MyClass
{
    [Editor(typeof(NoneEditor), typeof(UITypeEditor))]
    public string MyText { get; set; }

    public string MyOtherText { get; set; }
}

Обратите внимание, что свойство MyText украшено редактором "маркер", который просто ничего не делает:

public class NoneEditor : UITypeEditor
{
    public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
    {
        return UITypeEditorEditStyle.None;
    }
}

Я могу просто подключить сетку, например:

propertyGrid1.SelectedGridItemChanged += OnPropertyGridSelectedGridItemChanged;

    public static void OnPropertyGridSelectedGridItemChanged(object sender, SelectedGridItemChangedEventArgs e)
    {
        PropertyGrid pg = (PropertyGrid)sender;
        GridItem item = e.NewSelection;

        // yes, a grid item is also an IServiceProvider
        IServiceProvider sp = (IServiceProvider)item;

        // get the property grid view control
        IWindowsFormsEditorService svc = (IWindowsFormsEditorService)sp.GetService(typeof(IWindowsFormsEditorService));

        // WARNING: hack time! this uses private members, so use at your own risks...
        TextBox edit = (TextBox)svc.GetType().GetProperty("Edit", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(svc, null);

        // is this our funky stuff?
        if (item.PropertyDescriptor.GetEditor(typeof(UITypeEditor)) is NoneEditor)
        {
            edit.MaxLength = 10;
            edit.BackColor = Color.Blue;
        }
        else // don't forget to reset the edit box here
        {
            edit.MaxLength = int.MaxValue;
            edit.BackColor = Color.White;
        }
    }
  • 0
    Я использовал вариант вашего хука в SelectedGridItemChanged , и он работал очень хорошо. Я пошел по пути подкласса PropertyGrid ... и в конце концов забрел на что-то подобное. Благодарю.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню