帮助您在 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 属性窗口中的结果。查看我们添加的对话框底部的Red、Green、Blue: