如何覆盖 ColorEditor 类的 ColorUI 类并添加具有自定义颜色的新选项卡?

2023-12-02

我想做的是添加具有自定义颜色的自定义选项卡进入ColorUI class of 颜色编辑器 class这出现在PropertyGrid of controls.

像这样的东西:(只是用 Photoshop 制作的假图像 ).

enter image description here

我明白在某种程度上我必须创造自己的颜色编辑器 class and override the ColorUI class嵌套在原来的内部颜色编辑器 class但我不知道哪个Method我必须override所以要添加这个额外的Tab etc.

任何想法?


可能更灵活(并且更少黑客)的解决方案将重新创建ColorEditor正如吉米提到的。我还可能采用完全不同的方法来支持主题颜色,例如创建主题扩展程序提供程序组件,或创建派生控件或其他可能的解决方案。

不管怎样,支持我的上一篇文章,特别是我提到的'您甚至可以向编辑器添加另一个选项卡。',这里我发布了一个示例代码,用于向颜色编辑器添加另一个选项卡,然后您可以看到带有您需要的自定义颜色的自定义选项卡(主题),如下所示:

enter image description here

这是一个真实的屏幕截图;)不完全符合您的要求,但作为示例代码已经足够好了。例如,如果您需要使用颜色的自定义名称,那么您需要更多自定义DrawItem(就像我在示例中所做的那样),或者从头开始重写控件。

这是代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Design;
using System.Linq;
using System.Reflection;
using System.Windows.Forms;
public class CustomColorEditor : ColorEditor
{
    public override object EditValue(ITypeDescriptorContext
        context, System.IServiceProvider provider, object value)
    {
        //Get required types and methods
        var ColorUIType = typeof(ColorEditor).GetNestedType("ColorUI",
            BindingFlags.NonPublic | BindingFlags.Instance);
        var ColorUiConstructor = ColorUIType.GetConstructors()[0];
        var ColorEditorListBoxType = ColorUIType.GetNestedType("ColorEditorListBox",
            BindingFlags.NonPublic | BindingFlags.Instance);
        var ColorUiField = typeof(ColorEditor).GetField("colorUI",
            BindingFlags.NonPublic | BindingFlags.Instance);
        var OnListClickMethod = ColorUIType.GetMethod("OnListClick",
            BindingFlags.NonPublic | BindingFlags.Instance);
        var OnListDrawItemMethod = ColorUIType.GetMethod("OnListDrawItem",
            BindingFlags.NonPublic | BindingFlags.Instance);
        var OnListKeyDownMethod = ColorUIType.GetMethod("OnListKeyDown",
            BindingFlags.NonPublic | BindingFlags.Instance);

        //Color UI Control
        var colorUi = (Control)ColorUiConstructor.Invoke(new[] { this });
        ColorUiField.SetValue(this, colorUi);

        //Custom colors ListBox
        var listBox = (ListBox)Activator.CreateInstance(ColorEditorListBoxType);
        //Colors
        listBox.Items.AddRange(new object[] { Color.Red, Color.Green, Color.Blue });
        listBox.DrawMode = DrawMode.OwnerDrawFixed;
        listBox.BorderStyle = BorderStyle.FixedSingle;
        listBox.IntegralHeight = false;
        listBox.Sorted = false;
        listBox.Click += (sender, e) =>
            OnListClickMethod.Invoke(colorUi, new[] { sender, e });
        //Custom paint
        listBox.DrawItem += OnListDrawItem;
        //Original paint
        //listBox.DrawItem +=(sender, e) =>
        //    OnListDrawItemMethod.Invoke(colorUi, new[] { sender, e });
        listBox.DrawItem += OnListDrawItem;
        listBox.KeyDown += (sender, e) =>
            OnListKeyDownMethod.Invoke(colorUi, new[] { sender, e });
        listBox.Dock = DockStyle.Fill;

        //Add the custom tab page, including the custome colors
        var tabControl = colorUi.Controls.OfType<TabControl>().First();
        var customTabPage = new TabPage();
        customTabPage.Text = "Theme";
        customTabPage.Controls.Add(listBox);
        tabControl.TabPages.Add(customTabPage);
        return base.EditValue(context, provider, value);
    }
    private void OnListDrawItem(object sender, DrawItemEventArgs e)
    {
        var colorNames = new Dictionary<int, string>
        {
            {Color.Red.ToArgb(), "Blood"},
            {Color.Green.ToArgb(), "Life potion"},
            {Color.Blue.ToArgb(), "Water"},
        };
        ListBox lb = (ListBox)sender;
        object value = lb.Items[e.Index];
        e.DrawBackground();
        this.PaintValue(value, e.Graphics,
            new Rectangle(e.Bounds.X + 2, e.Bounds.Y + 2, 22, e.Bounds.Height - 4));
        e.Graphics.DrawRectangle(SystemPens.WindowText,
            new Rectangle(e.Bounds.X + 2, e.Bounds.Y + 2, 22 - 1, e.Bounds.Height - 4 - 1));
        var color = (Color)value;
        var name = colorNames.ContainsKey(color.ToArgb()) ? colorNames[color.ToArgb()] : color.Name;
        using (var foreBrush = new SolidBrush(e.ForeColor))
            e.Graphics.DrawString(name, lb.Font, foreBrush, e.Bounds.X + 26, e.Bounds.Y);
    }
}
public class MyControl : Control
{
    [Editor(typeof(CustomColorEditor), typeof(UITypeEditor))]
    public Color MyColor { get; set; }
}

Note:它依赖于颜色编辑器的实现细节,例如,在.NET 5+中,成员字段名称是“_colorUI”。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何覆盖 ColorEditor 类的 ColorUI 类并添加具有自定义颜色的新选项卡? 的相关文章

  • 如何启动异步任务对象

    我想开始收集Task同时处理对象并等待所有对象完成 下面的代码显示了我想要的行为 public class Program class TaskTest private Task createPauseTask int ms works w
  • Dotnet“新”命令不适用于 Framework 4.5?

    我正在尝试使用 dotnet 创建 4 5 框架类库项目new命令如下 dotnet new classlib lang C f net45 o TestProject 错误 无效参数 f 网络45 net45 不是 f 框架 的有效值 如
  • 操作/Lambda 表达式内存管理问题

    我将一个操作存储在局部变量中 然后在该局部变量超出范围后使用 使用前是否有被清理的危险 这是一个例子 public List GetMaps Action
  • Confuser .NET 混淆器。安全吗? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我目前正在开发一个应用程序 其中阻止用户反编译代码非常重要 现在 我意识到 如果由经验丰富的程序员执行 大多数 exe 都是可反编译的
  • 在 C# 中调用事件处理程序

    我一直在尝试学习如何在 C 中使用事件处理程序 但我无法弄清楚 handler this e 在以下代码中的作用 public event EventHandler ThresholdReached protected virtual vo
  • 读取STM32 MCU SPI数据寄存器的值

    有很多类似的问题 但似乎没有一个问题完全相同 我正在将 STML4 MCU 连接到 6 轴传感器 LSM6DS3 我已经成功地在 I2C 中实现了所有内容 但想要 SPI 的额外速度 和 DMA 如果我能让这些第一步工作起来的话 因此 第一
  • WinForms - 表单大小错误

    我们有以下代码 private void MainForm Shown object sender EventArgs e RepositionForm private void RepositionForm Rectangle rect
  • Qt QML 数据模型似乎不适用于 C++

    我一直在使用中的示例http doc qt digia com 4 7 qdeclarativemodels html http doc qt digia com 4 7 qdeclarativemodels html这是 QML 声明性数
  • 命名空间“Microsoft”中不存在类型或命名空间名称“Practices”

    我正在使用 Microsoft Visual Studio 2005 for c 我的代码中有以下命名空间 using Microsoft Practices EnterpriseLibrary using Microsoft Practi
  • 如何填充两个样条线或直线系列之间的区域

    我有这个Chart 如何填充两个之间的区域Series S0 and S1 说蓝色和黄色Series 为此 我们编写了其中之一Paint事件 这里的ValueToPixelPosition https msdn microsoft com
  • ASP.NET MVC 路由 - 向路由添加 .html 扩展名

    我对 MVC 和路由非常陌生 我被要求修改一个应用程序以使用不同的 url 由于我没有经验 这项任务对我来说有点困难 好吧 让我们谈谈一些代码 routes MapRoute CategoryBySeName Route name prod
  • DotNET 应用程序中的 GDI 句柄

    我的纯 DotNET 库作为非托管桌面应用程序中的插件运行 我收到了稳定的 虽然低 崩溃报告流 这些报告似乎表明 GDI 句柄存在问题 错误消息中的字体等 恢复为系统字体 各种控件的显示崩溃 不久后发生大规模崩溃 我的窗体几乎没有控件 但我
  • printf() 使用字符串表“解码器环”调试库

    我写这封信是想看看你们中是否有人见过或听说过我即将描述的想法的实现 我有兴趣为嵌入式目标开发 printf 风格的调试库 目标非常遥远 并且我和目标之间的通信带宽预算非常紧张 因此我希望能够以非常有效的格式获取调试消息 通常 调试语句如下所
  • 数组与映射的性能

    我必须循环一个大数组中的元素子集 其中每个元素都指向另一个元素 问题来自于检测大图中的连接组件 我的算法如下 1 考虑第一个元素 2 将下一个元素视为前一个元素所指向的元素 3 循环直到没有发现新元素 4 考虑1 3中尚未考虑的下一个元素
  • 该组件没有由 uri 标识的资源

    我想创建一个通用数据网格以在我的所有视图 用户控件上使用 这是我的结构 Class Library called Core Class called ViewBase public class ViewBase UserControl pu
  • 从 exit() 和 fork() 返回的结果奇怪地发生了位移

    我有一个 C 代码 有时会自行分叉 每个分叉都会执行一些操作 然后返回一个错误代码 目前 每个子进程返回其 ID 0 n void other int numero exit numero int main for int i 0 i lt
  • C# Julian 日期解析器

    我在电子表格中有一个单元格 它是 Excel 中的日期对象 但当它来自 C1 的 xls 类时 它会变成双精度型 类似于 2009 年 1 月 7 日的 39820 0 我读到这是儒略日期格式 有人可以告诉我如何在 C 中将其解析回 Dat
  • 参数数量在编译时确定的 Lambda 函数

    我想声明一个带有 N 个参数的 lambda 函数 其中 N 是模板参数 就像是 template
  • 为什么我不能对普通变量进行多态?

    我是一名Java程序员 最近开始学习C 我对某事感到困惑 据我了解 在 C 中 要实现多态行为 您必须使用指针或引用 例如 考虑一个类Shape与实施的方法getArea 它有几个子类 每个子类都以不同的方式重写 getArea 然后考虑以
  • 获取会议组织者邮件地址 EWS API

    我想使用 EWS API 获取会议组织者的邮件地址 目前 我刚刚获得约会项目的一些属性 我听说你可以设置你想要获取哪些属性 我的代码看起来像这样 CalendarView cview new CalendarView start end c

随机推荐