Предоставить свойство типа List<class> в VS Designer Ограничить / скрыть доступ к элементам или показать свойство как расширяемое меню?

Я создал пользовательский элемент управления вкладками для своего приложения Windows. Пользовательский элемент управления вкладками расширяет System.Windows.Forms.TabControl. Причина, по которой я создал пользовательский элемент управления вкладками, заключается в том, что я могу предоставить свойство в окне свойств Visual Studio, которое позволяет мне определять отдельные шрифты для каждой вкладки в пользовательском элементе управления вкладками. Вот быстрый взгляд на определение класса:

[ToolboxItem(true)]    
public partial class CustomTabControl : System.Windows.Forms.TabControl

Для хранения каждой отдельной пары имя / шрифт я создал вложенный класс внутри CustomTabControl:

[TypeConverter(typeof(TabFontConverter))]
public class TabFont
{
    public string Name { get; set; }
    public Font Font { get; set; }        
    public TabFont()
    {
    }        
    public TabFont(string name, Font font)
    {
        this.Name = name;
        this.Font = font;
    }
}

(Обратите внимание на использование свойства TypeConverter над классом TabFont. Я добавил это, потому что где-то в Интернете я читал, что это требуется, если я собираюсь представить этот тип в конструкторе Visual Studio.)

Вот класс конвертера (который также вложен в CustomTabControl):

public class TabFontConverter : TypeConverter
{
    public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] filter)
    {
        return TypeDescriptor.GetProperties(value, filter);
    }

    public override bool GetPropertiesSupported(ITypeDescriptorContext context)
    {
        return true;
    }
}

Я определил переменную класса для хранения пользовательских шрифтов табуляции в виде списка:

private List<TabFont> _CustomTabFonts = new List<TabFont>();

Чтобы заполнить этот список, я добавил обработчик событий для ControlAdded:

this.ControlAdded += new ControlEventHandler(CustomTabControl_ControlAdded);

Вот как я заполняю список внутри обработчика событий:

private void CustomTabControl_ControlAdded(object sender, ControlEventArgs e)
{
    if (e.Control.GetType() == typeof(TabPage))
    {
        TabPage newTabPage = (TabPage)e.Control;
        Font newTabPageFont = newTabPage.Font;
        _CustomTabFonts.Add(new TabFont(newTabPage.Text, newTabPageFont));
        e.Control.Font = newTabPageFont;
    }
}

И, наконец, чтобы связать все это, я определил следующий код, позволяющий конструктору Visual Studio получать доступ / изменять список шрифтов пользовательской вкладки:

[DefaultValue(typeof(List<TabFont>))]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
public List<TabFont> CustomTabFonts
{
    get { return _CustomTabFonts; }
    set { _CustomTabFonts = value; }
}

После перестройки я снова переключаюсь в представление дизайна Visual Studio, добавляю CustomTabControl в основную форму, перетаскивая одну из панели инструментов. Затем я добавил 2 вкладки с именами "Tab 1" и "Tab 2".

Это то, что окно свойств показывает для моего свойства пользовательских шрифтов вкладки:

Свойство стандартных шрифтов на вкладке

Обратите внимание, что он показывает тип как коллекцию и предоставляет кнопку [...], которую можно щелкнуть для редактирования. Когда я нажимаю кнопку вот что я вижу:

Редактор свойств стандартных шрифтов на вкладке

У меня есть пара вопросов относительно редактора недвижимости.

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

  • В левой части редактора свойств отображается список вкладок, что именно то, что я хочу. Однако я не хочу разрешать перемещение, добавление или удаление любого из этих участников. Как я могу скрыть или отключить кнопки перемещения (стрелки вверх / вниз) и добавления / удаления?

  • В левой части редактора свойств есть заголовок "Участники". Могу ли я изменить это, чтобы сказать, что я хочу? Что-то вроде "Tab Pages" и т. Д.

  • В правой части редактора свойств есть заголовок "Разное". Могу ли я это изменить?

Большое спасибо.

январь

____ОБНОВИТЬ____

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

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

Пользовательская вкладка Шрифты Свойство Предпочитаемый

1 ответ

Я не могу ответить на вопрос об обновлении, но я остановлюсь на двух других: Изменение текста "Члены": единственный способ увидеть это - создать собственный CollectionEditor, который открывает пользовательский CollectionEditor.CollectionForm., Я не пробовал это все же. Остановка появления свойства "Имя" в редакторе. Да, это можно сделать в методе TypeConverter.GetProperties, отфильтровав результат. Я не нашел аргумента "фильтра" для метода TypeDescriptor.GetProperties, но это может быть потому, что я не использовал его правильно. Проблема в том, что после создания PropertyDescriptorCollection доступна только для чтения, поэтому я скопировал содержимое результата, но пропустил элемент, который мне не нужен. Это должно работать:

    public class TabFontConverter : TypeConverter
    {
        public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] filter)
        {
            PropertyDescriptorCollection rawResult = TypeDescriptor.GetProperties(value, filter);
            PropertyDescriptor[] arrRawResult = new PropertyDescriptor[rawResult.Count - 1];

            int i = 0;
            int j = 0;
            while (i < rawResult.Count)
            {
                if (rawResult[i].Name != "Name")
                {
                    arrRawResult[j] = rawResult[i];
                    j++;
                }
                i++;
            }
            PropertyDescriptorCollection filteredResult = new PropertyDescriptorCollection(arrRawResult);

            return filteredResult;
        }
Другие вопросы по тегам