当前位置:首页 > 人生 > 作品墙 > 正文内容

ARGB颜色对话框 ArgbColorDialog 控件调用文档

作品墙1周前 (10-23)



命名空间:CConUI
类型:public static class ArgbColorDialog
定位:运行时用的 ARGB 颜色选择对话框(模态)。
内部把 ArgbColorPicker(下拉面板)包装成一个独立的 Form,通过一个内部适配器 FormEditorService 把「关闭下拉」的语义映射为「设置 DialogResult = OK 并关闭窗体」。

与属性网格编辑器的关系:
- 设计时(属性面板里点色块)使用的是 ArgbColorEditor(UITypeEditor);
- 运行时(例如按钮点击后弹窗选色)使用的是 ArgbColorDialog.Show(...);
- 两者最终都是复用 ArgbColorPicker 的 UI。


一、公开成员一览

成员类型说明
Show(Color? initial = null, IWin32Window owner = null)public static 方法弹出模态对话框,返回用户选择的颜色或 null

本类只有 1 个公开方法(Show)。内部类 FormEditorService 是 private,外部无法访问。


二、方法签名

public static Color? Show(Color? initial = null, IWin32Window owner = null)

项目说明
签名public static Color? Show(Color? initial = null, IWin32Window owner = null)
类/方法性质static(无需实例化,直接 ArgbColorDialog.Show(...))
作用弹出一个模态的 ARGB 颜色选择对话框,等待用户操作后返回结果

三、参数说明

1) Color? initial = null

项目说明
类型System.Drawing.Color?(可空 Color)
是否必填否(有默认值 null)
含义对话框初始显示的颜色(A/R/G/B 四个输入框、Alpha 滑块、预览条都会以此初始化)
为 null 时内部兜底为 Color.Black
保留 Alpha传入的 Alpha 会完整保留(不做强制 255)
// 用当前颜色作为初始色
ArgbColorDialog.Show(this.BackColor);

// 用半透明红色作为初始色(A=128)
ArgbColorDialog.Show(Color.FromArgb(128, 255, 0, 0));

// 使用默认(黑)
ArgbColorDialog.Show(null);

2) IWin32Window owner = null

项目说明
类型System.Windows.Forms.IWin32Window
是否必填否(有默认值 null)
含义宿主窗口;通过 host.ShowDialog(owner) 传给 Form,作为模态父窗口
为 null 时调用无参 ShowDialog(),没有父窗口
作用影响焦点/激活行为(有 owner 时,owner 会被禁用,避免用户切到父窗口)
// 推荐:在窗体内部调用时把 this 传进去
ArgbColorDialog.Show(Color.Gray, this);

// 无 owner
ArgbColorDialog.Show(Color.Gray);

关于弹出位置:本方法在内部把 StartPosition 设成了 Manual,不使用 owner 的居中,而是固定在鼠标位置右下偏移 +10, +10 像素处(并做屏幕工作区防溢出)。owner 只影响模态/焦点行为,不影响位置。


四、返回值

返回情况值触发条件
用户确认Color(HasValue == true)用户点击对话框里的「确认」按钮,或双击色板色块
用户取消null(HasValue == false)按 Esc、点击窗体右上角关闭按钮,或其它 DialogResult != OK 情况
Color? picked = ArgbColorDialog.Show(Color.White, this);
if (picked.HasValue)
{
    // 用户确认了一个颜色
    this.BackColor = picked.Value;
}
else
{
    // 用户取消,什么也不做
}

五、调用方式(常用模式)

模式 1:作为属性/字段更新

using System.Drawing;
using System.Windows.Forms;
using CConUI;

private Color _themeColor = Color.FromArgb(255, 0, 120, 215);

private void btnPickThemeColor_Click(object sender, EventArgs e)
{
    Color? c = ArgbColorDialog.Show(_themeColor, this);
    if (c.HasValue)
    {
        _themeColor = c.Value;
        // 应用到某个控件
        panel1.BackColor = _themeColor;
        // 如果目标控件属性的编辑器是 ArgbColorEditor,也可通过属性面板改
    }
}

模式 2:批量修改多个控件的统一颜色

private void btnPickForeColor_Click(object sender, EventArgs e)
{
    Color? c = ArgbColorDialog.Show(Color.White, this);
    if (!c.HasValue) return;

    foreach (Control child in this.Controls)
    {
        if (child is Button btn) btn.ForeColor = c.Value;
    }
}

模式 3:配合属性网格里的属性(设计时)与运行时手动调用

// 假设有这么一个控件属性(设计时用 ArgbColorEditor 编辑)
[Editor(typeof(ArgbColorEditor), typeof(System.Drawing.Design.UITypeEditor))]
public Color AccentColor { get; set; }

// 运行时允许用户通过按钮重新选择
private void btnEditAccent_Click(object sender, EventArgs e)
{
    Color? c = ArgbColorDialog.Show(myControl.AccentColor, this);
    if (c.HasValue) myControl.AccentColor = c.Value;
}

模式 4:半透明颜色(注意保留 Alpha)

// 用半透明颜色初始化,用户在对话框里不动 Alpha 就会保留
Color semi = Color.FromArgb(128, 0, 120, 215);
Color? c = ArgbColorDialog.Show(semi, this);
if (c.HasValue)
{
    // c.Value.A 通常仍是 128(除非用户在对话框里改了 Alpha 滑块/输入框)
    label1.Text = $"A={c.Value.A}, R={c.Value.R}, G={c.Value.G}, B={c.Value.B}";
}

六、对话框交互一览

操作效果
点击 8×8 色板某格替换当前 RGB(Alpha 保持当前值),刷新预览、输入框、色板高亮框
双击色板某格等价于“点击该色块 + 点击确认” → 直接返回该颜色并关闭对话框
拖动 Alpha 滑块更新 Alpha 通道,刷新预览与 A 输入框
在 A / R / G / B 输入框打字只允许数字;越界值自动 Clamp 到 0–255;实时刷新预览
点击「确认」按钮提交当前值(SelectedColor = _current)→ FormEditorService.CloseDropDown() → 设置 DialogResult=OK → 关闭窗体 → Show 返回 picker.SelectedColor
按 Esc设置 DialogResult=Cancel → 关闭 → Show 返回 null
点右上角 X关闭 → DialogResult 为 Cancel → Show 返回 null

七、内部实现要点(了解即可,不需要调用)

项目说明
承载窗体临时 Form,FormBorderStyle.FixedDialog,标题「选择颜色 (ARGB)」,不显示任务栏
内容一个 ArgbColorPicker(Dock=Fill),构造参数是 startColor
尺寸host.ClientSize = picker.Size(picker 在构造时已按布局算好自己的 ClientSize)
初始位置Cursor.Position + (10, 10)
防溢出以 Screen.FromPoint(mousePos).WorkingArea 为工作区,四边越界时分别向左/上平移贴边
Eschost.KeyPreview = true + KeyDown 里判断 Keys.Escape
确认后的返回FormEditorService.CloseDropDown() 里先设 DialogResult=OK 再 Close(),ShowDialog() 因此返回 OK
// 伪代码,帮助理解内部时序:
// 1. 用户点「确认」
//    → ArgbColorPicker.BtnOk_Click
//    → picker.SelectedColor = 当前颜色
//    → picker.EditorService.CloseDropDown()
//      → host.DialogResult = OK
//      → host.Close()
// 2. Show() 里的 host.ShowDialog() 返回 DialogResult.OK
// 3. Show() 返回 picker.SelectedColor
// 4. using 块结束,host 被 Dispose

八、与其他类的配合对照

场景使用类调用方式
属性面板(设计时)里编辑 Color 属性ArgbColorEditor在属性上加 [Editor(typeof(ArgbColorEditor), typeof(UITypeEditor))]
运行时弹模态对话框ArgbColorDialogArgbColorDialog.Show(初始色, owner)
自定义承载(自行管理 UI)ArgbColorPicker(internal)外部程序集不可用;CConUI 内部才可 new ArgbColorPicker(...)
颜色预览框(带棋盘格)ColorPreviewBox(internal)外部不可用

九、注意事项

  1. 类名为 ArgbColorDialog(已修正零宽字符问题)。若在旧版源码中看到 ArgbColorDialog(中间藏有 U+200B 零宽空格),在外部引用时会编译不过——请使用本版本的正确名称。

  2. 该方法是模态的(阻塞式)。调用 Show(...) 后会阻塞当前 UI 线程直到对话框关闭;不要在后台线程调用。

  3. 不要在 UI 线程未运行的上下文(例如控制台程序)里直接调用,Form.ShowDialog 需要消息泵。

  4. initial 为 null 时才回退为黑色。如果传 Color.Transparent,会被完整保留(Alpha=0),此时预览区会完全显示棋盘格。

  5. 取消返回 null,而不是返回初始值。因此调用方需要自己判断 HasValue,不要误用 picked.Value。

  6. 双击色板 = 选中 + 确认。想“只选不关”请单击色块。

  7. 弹出位置由内部固定为鼠标 +10,+10,不受 owner 影响。如果你需要自定义位置,需要自己创建一个 Form 包裹 ArgbColorPicker(但 ArgbColorPicker 是 internal,外部程序集做不到——除非使用本程序集内部的扩展方法)。

  8. 不要长期持有 owner。对话框关闭后返回的颜色是值类型 Color,不引用任何 UI 对象。

  9. 返回值是精确的 Color(含 Alpha)。如果目标属性在设计时使用的是 ArgbColorEditor,运行时用本对话框设置同一个属性,效果一致(两者底层都是 ArgbColorPicker)。

  10. IWin32Window owner 通常是窗体或控件,例如 this(在 Form 内部);传 null 或 IntPtr.Zero 会导致没有父窗口,行为可能不符合用户预期(例如最小化宿主窗口时对话框不会一起最小化)。


十、完整示例

using System;
using System.Drawing;
using System.Windows.Forms;
using CConUI;

public partial class Form1 : Form
{
    private Color _accentColor = Color.FromArgb(255, 0, 120, 215);

    public Form1()
    {
        InitializeComponent();

        // 初始应用到某个控件
        panel1.BackColor = _accentColor;

        // 点击按钮打开颜色选择对话框
        btnChoose.Click += BtnChoose_Click;
    }

    private void BtnChoose_Click(object sender, EventArgs e)
    {
        Color? picked = ArgbColorDialog.Show(_accentColor, this);

        if (picked.HasValue)
        {
            _accentColor = picked.Value;
            panel1.BackColor = _accentColor;

            // 半透明时同步展示 Alpha
            lblInfo.Text = string.Format(
                "A={0}, R={1}, G={2}, B={3}",
                _accentColor.A, _accentColor.R, _accentColor.G, _accentColor.B);
        }
        else
        {
            lblInfo.Text = "已取消选择";
        }
    }
}

转载请注明出处。

本文链接:http://www.pythonopen.com/?id=7973

相关文章

已经实现的一些算法

编码CConA1是一种可复原的编码算法,用于将文本或字节转换为纯字母。可用于文件名混淆,避免因包含违...

横向滚动条HScrollBar 控件调用文档

命名空间:CConUI继承:System.Windows.Forms.Control版本:基于所提供...

纵向滚动条VScrollBar 控件调用文档

命名空间:CConUI继承:System.Windows.Forms.Control版本:基于所提供...

菜单MenuItem 与 ContextMenu 控件调用文档

命名空间:CConUI依赖:System.Windows.Forms、System.Drawing、...

图片框PictureBox 控件调用文档

命名空间:CConUI继承:System.Windows.Forms.Control定位:自绘图片框...

蚂蚁线AntLine 控件调用文档

命名空间:CConUI继承:System.Windows.Forms.Control定位:虚线蚂蚁线...