Custom color palette in the Visual Studio Color Printing Property Editor

Inside Visual Studio Designer, in the properties window, you can select ForeColor , BackColor , etc. using color picker. When you want to select a color, the Custom Website tabs appear in the color picker. If you select custom, you can add a new color to the collector, but only the bottom 2 lines can change, and the changes are not saved on the controls. Therefore, if you add color to the palette when you select another control and want to change, for example, BackColor , your previous added color does not exist.

Is there a way to create and import a custom color set into a color designer control?

Note. . This question does not ask VS topics, or colors can be implemented as a class in code. I am in favor of adapting the designer.

+7
source share
2 answers

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:

enter image description here

+7
source

I know that a lot of time has passed.

You can use MergedDictionaries and reference the resource dictionary in the App.xml file.

This will put the colors that you define in the palette, but you will need to include the same resource dictionary and specify it in each App.xaml application for each application you use, which, in my opinion, is good, because sometimes you have to use custom colors for different applications. Custom color palette

Something like that

0
source

Source: https://habr.com/ru/post/1244563/


All Articles