Visual Studio颜色属性编辑器中的自定义调色板

时间:2016-03-07 09:33:53

标签: c# .net winforms visual-studio windows-forms-designer

在Visual Studio Designer中,在属性窗口下,您可以使用颜色选择器选择ForeColorBackColor等。当您想要选择颜色时,颜色选择器会出现“自定义,Web,系统”选项卡。 如果选择自定义,则可以向选择器添加新颜色,但只有底部2行可以更改,并且更改不会在控件之间保留。因此,如果您向调色板添加颜色,当您选择其他控件并希望更改时,例如BackColor您之前添加的颜色就不存在。

有没有办法在设计师的颜色选择器控件中创建和导入一组自定义颜色?

注意:这个问题不是询问VS主题,还是可以在代码隐藏中将颜色实现为类。我正在寻找一种定制设计师的方法。

3 个答案:

答案 0 :(得分:7)

帮助您在visual studio中选择颜色的编辑器是ColorEditor,它不会在不同的控件中保留自定义颜色。要解决这个问题,你应该:

  • 根据ColorEditor
  • 创建自定义UITypeEditor
  • 在visual studio startup
  • 注册类型为Color的编辑器

这是一个详细的答案,包括我用来解决问题的代码。

创建CustomColorEditor

ColorEditor使用私有ColorUI类来显示私有ColorPalette控件。调色板使用一系列颜色来显示自定义颜色。

要创建CustomColorEditor我从ColorEditor派生并使用反射,找到这些成员并使用某些颜色的静态数组填充数组,以便在首次加载时显示。关闭编辑器后,我从编辑器中获取自定义颜色并将它们放入静态数组中,并在下次加载时使用此静态数组初始化颜色编辑器。这样,我的CustomColorEditor的所有实例之间共享自定义颜色。

显示CustomColorEditor而非默认ColorEditor

要为特定类型的所有属性显示ui类型编辑器,您应该为该类型添加Editor属性。但由于Color不是我的类型,我怎么能为其添加Editor属性?

TypeDescriptor.AddAttributes帮助我注册了Color类型的编辑器。

我应该在哪里运行代码来注册属性?肯定是在视觉工作室运行时!

为此,我创建了一个Visual Studio Package项目,并将注册码放在Initialize方法包中。我还在包类中添加了ProvideAutoLoad属性,以便在我打开解决方案时自动加载。

然后我安装了包。

然后我使用gacutil.exe /i "path to dll"将dll放入GAC。而不是GAC也可以将Visual Studio中的dll放在devenv.exe附近,因为视觉stusio运行时将使用它来显示我所有颜色属性的自定义颜色编辑器。

<强>结论

执行上述任务后,我打开了一个新的visual studio实例,在我的Windows Forms项目中,我看到我的自定义颜色编辑器显示颜色。我设置的初始颜色显示。此外,颜色编辑器甚至在不同形式之间保持自定义颜色!

我在这里分享了代码。您可以使用该想法和代码来增强编辑器。您可以在开始时提供自定义颜色以在编辑器中显示。您甚至可以向编辑器添加另一个选项卡。这是我的代码:

色彩编辑器代码

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

套餐代码

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

<强>结果

这将是Visual Studio属性窗口中的结果。查看我们添加的对话框底部的RedGreenBlue

enter image description here

答案 1 :(得分:0)

我知道已经有一段时间......

您可以使用MergedDictionaries并在App.xml文件中引用资源字典。

这会将你在调色板中定义的颜色放在一起,但是你必须包含相同的资源字典并在每个App.xaml中为你使用的每个应用程序引用它,在我看来,这很好,因为有时候你需要为不同的应用程序使用自定义颜色。Custom Color Palette

像这样的东西

答案 2 :(得分:-1)

编写在颜色对话框中显示颜色属性的代码