There is a standard collection editor with an overloaded base class. I would like to change the appearance of the drop-down list, for example, highlight some lines with bold or other colors. Is it possible to do this and how, if possible.

enter image description here

    1 answer 1

    WinForms does not give a lot of fields for customization (or gives, but with a fight). Something you can do.

    For any type / property, you can override the editor using the Editor attribute:

     public class Foo { [Editor(typeof(CustomEditor), typeof(UITypeEditor))] public string Bar { get; set; } } 

    To do this, you need to implement 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; } } 

    Application itself:

     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); } } 

    A few more brief examples can be found in the CodeProject article .

    • Thank. As soon as I manage to rewrite it on VB and get positive results, I will mark your answer as correct. - Dmitry Gvozd