Имеется стандартный редактор коллекции с перегруженным базовым классом.
Хотелось бы изменить внешний вид выпадающего списка, например некоторые строки выделить жирным шрифтом или другим цветом. Можно ли это сделать и как если можно.
Ответ
WinForms не дает много поля для кастомизации (или дает, но с боем). Кое-что сделать можно.
Для любого типа/свойства можно переопределять редактор с помощью атрибута Editor
public class Foo
{
[Editor(typeof(CustomEditor), typeof(UITypeEditor))]
public string Bar { get; set; }
}
Для этого нужно имплементировать UITypeEditor
public class CustomEditor : UITypeEditor
{
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
{
// говорим, что это будет выпадающий список
// есть вариант Modal, при котором мы можем показать форму в качестве редактора
return UITypeEditorEditStyle.DropDown;
}
public override object EditValue(ITypeDescriptorContext context, System.IServiceProvider provider, object value)
{
// context -- содержит информацию о текущем свойстве и родительском объекте
// provider -- дает сервис, с помощью которого можно отображать кастомные редакторы
// value -- содержит непосредственно редактируемый объект
IWindowsFormsEditorService service = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
var list = new ListBox()
{
SelectionMode = SelectionMode.One,
DrawMode = DrawMode.OwnerDrawFixed
};
// не забываем закрыть выпадающий список после того, как было выбрано значение
list.SelectedValueChanged += (s, e) => service.CloseDropDown();
list.DrawItem += (s, e) =>
{
// кастомизация шрифта (жирный/нежирный)
e.DrawBackground();
var font = e.Index % 2 == 0
? new Font("Arial", 9, FontStyle.Bold)
: new Font("Arial", 9);
e.Graphics.DrawString(
list.Items[e.Index].ToString(),
font,
Brushes.Black,
e.Bounds);
e.DrawFocusRectangle();
};
// заполняем список ерундой
for (int i = 1; i <= 5; i++ )
{
list.Items.Add(i.ToString());
}
// устанавливаем текущее значение в качестве выбранного
list.SelectedItem = value;
// показываем выпадающий список, показывать можно любой контрол
service.DropDownControl(list);
// возвращаем выбранное в списке значение в качестве нового значения
return list.SelectedItem;
}
}
Само приложение:
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Form form = new Form()
{
Controls =
{
new PropertyGrid()
{
Dock = DockStyle.Fill,
SelectedObject = new Foo()
}
}
};
Application.Run(form);
}
}
Еще несколько кратких примеров можно найти в статье на CodeProject
Комментариев нет:
Отправить комментарий