An editor that helps you select colors in Visual Studio is the ColorEditor
, which does not preserve custom colors for different controls. To solve the problem, you need to:
- Create a custom
UITypeEditor
based on ColorEditor
- Register an editor for type
Color
when starting Visual Studio
Here is a detailed answer, including codes that I used to solve the problem.
Create CustomColorEditor
ColorEditor
uses the private ColorUI
class to display a private ColorPalette
control. The palette uses an array of colors to display custom colors.
To create a CustomColorEditor
, I got from ColorEditor
and, using reflection, I found these elements and filled the array using a static array of some colors to show on first boot. Then, after closing the editor, I get the custom colors from the editor, put them in a static array and initialize the color editor using this static array the next time I load it. This way, custom colors are shared between all instances of my CustomColorEditor
.
Show CustomColorEditor instead of the default ColorEditor
To show the user interface type editor for all properties of a particular type, you must add the Editor
attribute to the type. But since Color
not of my type, how can I add the Editor
attribute to it?
TypeDescriptor.AddAttributes
helped me register an editor for type Color
.
Where can I run the code to register an attribute? Of course, during the visual studio!
To do this, I created a Visual Studio package project and placed the registration code in the Initialize
package method. I also added the ProvideAutoLoad
attribute to the package class so that it ProvideAutoLoad
automatically when the solution opens.
Then I installed the package.
Then I put the DLL in the GAC using gacutil.exe /i "path to dll"
. Instead of the GAC, you can also place the dll in Visual Studio next to devenv.exe
, since the visual stusio runtime will use it to display my custom color editor for all color properties.
Conclusion
Having completed the above tasks, I opened a new instance of Visual Studio and in my Windows Forms project I see my own color editor displayed for colors. The initial colors that I set are displayed. In addition, the color editor has retained custom colors even between different shapes!
I shared the codes here. You can use the idea and codes to improve the editor. You can provide your own colors for display in the editor at startup. You can even add another tab to the editor. Here are my codes:
Color Editor Code
class CustomColorEditor : ColorEditor { private static Color[] Colors; static CustomColorEditor() { Colors = new Color[]{ Color.Red, Color.Green, Color.Blue, Color.White, Color.White, Color.White, Color.White, Color.White, Color.White, Color.White, Color.White, Color.White, Color.White, Color.White, Color.White, Color.White, }; } public override object EditValue(ITypeDescriptorContext context, System.IServiceProvider provider, object value) { var colorEditorObject = this; Type colorUiType = typeof(ColorEditor).GetNestedType("ColorUI", BindingFlags.NonPublic); var colorUiConstructor = colorUiType.GetConstructors()[0]; var colorUiField = typeof(ColorEditor).GetField("colorUI", BindingFlags.Instance | BindingFlags.NonPublic); var colorUiObject = colorUiConstructor.Invoke(new[] { colorEditorObject }); colorUiField.SetValue(colorEditorObject, colorUiObject); var palField = colorUiObject.GetType().GetField("pal", BindingFlags.Instance | BindingFlags.NonPublic); var palObject = palField.GetValue(colorUiObject); var palCustomColorsField = palObject.GetType().GetField("customColors", BindingFlags.Instance | BindingFlags.NonPublic); palCustomColorsField.SetValue(palObject, Colors); var selectedValue = base.EditValue(context, provider, value); Colors = palCustomColorsField.GetValue(palObject) as Color[]; return selectedValue; } }
Code for the package
[PackageRegistration(UseManagedResourcesOnly = true)] [InstalledProductRegistration("#110", "#112", "1.0", IconResourceID = 400)] [Guid(GuidList.guidVSPackage1PkgString)] [ProvideAutoLoad(Microsoft.VisualStudio.Shell.Interop.UIContextGuids80.SolutionExists)] public sealed class VSPackage1Package : Package { public VSPackage1Package() { } protected override void Initialize() { base.Initialize(); TypeDescriptor.AddAttributes(typeof(Color), new EditorAttribute(typeof(CustomColorEditor), typeof(UITypeEditor))); } }
Result
This will be the result in the Visual Studio Properties window. Look at those Red
, Green
, Blue
at the bottom of the dialog that we added:
