【问题标题】:Custom Color Palette in Visual Studio Color Property EditorVisual Studio 颜色属性编辑器中的自定义调色板
【发布时间】:2016-03-07 09:33:52
【问题描述】:

在 Visual Studio 设计器中,在属性窗口下,您可以使用颜色选择器选择 ForeColorBackColor 等。当您想选择颜色时,颜色选择器会出现“自定义、Web、系统”选项卡。 如果您选择自定义,那么您可以向选择器添加新颜色,但只有底部 2 行是可更改的,并且更改不会在控件之间持续存在。因此,如果您向调色板添加颜色,当您选择另一个控件并想要更改例如 BackColor 时,您之前添加的颜色不存在。

有没有办法创建自定义颜色集并将其导入设计器的颜色选择器控件?

注意:这个问题不是关于 VS 主题,或者颜色是否可以在代码隐藏中作为一个类来实现。我正在寻找一种方法来定制设计师。

【问题讨论】:

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


    【解决方案1】:

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

    • 基于ColorEditor创建自定义UITypeEditor
    • 在 Visual Studio 启动时注册类型 Color 的编辑器

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

    创建自定义颜色编辑器

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

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

    显示 CustomColorEditor 而不是默认的 ColorEditor

    要为特定类型的所有属性显示 ui 类型编辑器,您应该为该类型添加一个 Editor 属性。但是既然Color不是我的类型,那我怎么给它加上Editor属性呢?

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

    我应该在哪里运行代码来注册属性?肯定在 Visual Studio 运行时!

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

    然后我安装了这个包。

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

    结论

    执行上述任务后,我打开了一个新的 Visual Studio 实例,在我的 Windows 窗体项目中,我看到我的自定义颜色编辑器显示了颜色。我设置的初始颜色显示。即使在不同的表单之间,颜色编辑器也会保留自定义颜色!

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

    颜色编辑器代码

    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

    【讨论】:

      【解决方案2】:

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

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

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

      类似的东西

      【讨论】:

      • 问题被标记为 Windows 窗体。
      【解决方案3】:

      编写一段代码,在颜色对话框中显示颜色属性

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-07-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多