Angenommen, man braucht einen ganz einfach UITypeEditor, zum Beispiel einen, der in einer Listbox eine Auswahl an Möglichkeiten anbietet. Das ist verhältnismäßig einfach zu haben: Die Kurzform von so einem Ding sieht so aus:

public class StyleFilenameEditor : UITypeEditor
{
   public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
   {
      ListBox listBox = new ListBox();
      listBox.Items.Add("Text 1"); // usw.
      IWindowsFormsEditorService editorService = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
editorService.DropDownControl(listBox);
   

      return listBox.SelectedItem;
   }

   public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
   {   
      return UITypeEditorEditStyle.DropDown;
   }
}

Feine Sache, allerdings mit einem kleinen Haken: Man bekommt die Listbox nicht mehr zu, wenn man den Code so verwendet, wie ich ihn im Beispiel hingeschrieben habe. Grund: Der EditorService erwartet, das man ihm mitteilt, wenn er das zugehörige Drop-Down schliessen soll. Die offensichtliche Art ist dabei die folgende. Dabei merkt man sich den editorServive in einer privaten Variable, und hängt einen Event-Handler an das SelectedIndexChanged-Event der Listbox. In diesem Handler benutzt man dann die private Variable und ruf CloseDropdown auf:

      this.editorSerivce = ...

      listBox.SelectedIndexChanged +=new EventHandler(listBox_SelectedIndexChanged);

      void listBox_SelectedIndexChanged(object sender, EventArgs e)
      {
         this.editorService.CloseDrowDown();
      }

Mit einem anonymen Delegate geht das aber viel schöner. Man braucht keinen separaten Event-Handler und auch keine private Variable:

         listBox.SelectedIndexChanged += delegate(object sender, EventArgs e) { editorService.CloseDropDown(); };