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

菜单MenuItem 与 ContextMenu 控件调用文档

作品墙1周前 (10-23)



命名空间:CConUI
依赖:System.Windows.Forms、System.Drawing、System.Drawing.Design、CConPlus(CConPlus.Enum.ImageSizeMode、CConPlus.GraphicsC、CConPlus.Windows.API.USER32)
本程序集公开 2 个类:

类名可见性基类作用
MenuItempublicobject单个菜单项(含子项、分隔线、快捷键等)
ContextMenupublicSystem.ComponentModel.Component完全自绘的上下文菜单



一、MenuItem 菜单项

1.1 作用

表示上下文菜单中的单个条目,可作为:

  • 普通可点击项

  • 带快捷键提示的项

  • 分隔线

  • 带多级子菜单的父项

  • 禁用项 / 隐藏项

层级结构通过 Items(List<MenuItem>)实现,可无限嵌套。

1.2 构造函数

public MenuItem()

  • 创建一个空菜单项(Text="",其余使用默认值)。

var item = new MenuItem();
item.Text = "打开";

public MenuItem(string text)

参数类型说明
textstring菜单项显示文本;为 null 时存为 ""
var item = new MenuItem("复制");

public MenuItem(string text, EventHandler onClick)

参数类型说明
textstring显示文本;为 null 时存为 ""
onClickEventHandler点击事件处理器;null 时不订阅
var item = new MenuItem("退出", (s, e) => Application.Exit());

public MenuItem(bool isSeparator)

参数类型说明
isSeparatorbooltrue 表示创建分隔线
var sep = new MenuItem(true);

1.3 静态方法

public static MenuItem CreateSeparator()

项目说明
参数无
返回一个新的分隔线菜单项(内部等价 new MenuItem(true))
作用便捷创建分隔线
var sep = MenuItem.CreateSeparator();

1.4 公开属性

属性类型默认说明
Textstring""显示文本;分隔线时忽略
ShortcutKeyDisplayStringstring""快捷键显示文本(如 "Ctrl+C");仅显示不注册快捷键;有子菜单时不显示(右侧改为箭头)
Flagstring""自定义标识字符串,例如命令名、分组名、类型标记
Enabledbooltrue是否启用;禁用时显示为禁用色且点击不响应
Visiblebooltrue是否可见;不可见时不占位置、不绘制、不参与命中
IsSeparatorboolfalse是否为分隔线;为 true 时忽略 Text、ShortcutKeyDisplayString 等
ClickableWithSubMenuboolfalse拥有子菜单时是否仍可被点击;true 时点击同时触发展开和 Click
ItemsList<MenuItem>空列表子菜单集合(只读属性,但返回 List 对象本身,可直接 Add/Remove/Clear)
HasSubMenubool只读是否拥有至少一个可见子项;为 true 时才绘制右箭头并允许展开
IsClickablebool只读综合判定是否可点:
① 分隔线 → false
② Enabled=false → false
③ 有子菜单且 ClickableWithSubMenu=false → false
④ 否则 → true
Tagobjectnull自定义数据;不参与设计器序列化
var openItem = new MenuItem("打开");
openItem.ShortcutKeyDisplayString = "Ctrl+O";
openItem.Flag = "cmd.open";
openItem.Tag = 12345;

1.5 公开事件

public event EventHandler Click

  • 当菜单项被真正点击时触发。

  • 触发时机:由 ContextMenu 在鼠标左键按下与松开都命中同一项时调用,或通过 PerformClick() 手动触发。

item.Click += (s, e) => MessageBox.Show("点击了:" + ((MenuItem)s).Text);

1.6 公开方法

public void PerformClick()

项目说明
参数无
作用手动触发 Click 事件

通常在 ContextMenu 内部使用;外部若需模拟点击也可以调用(不会关闭菜单,需要自己再调用 ContextMenu.Close())。

myMenuItem.PerformClick();
contextMenu.Close();

public MenuItem AddSubItem(MenuItem item)

项目说明
参数item:要添加的子菜单项;null 时忽略
返回传入的 item(便于链式使用);传入 null 时返回 null
作用向当前项的 Items 追加一个子项
var file = new MenuItem("文件");
file.AddSubItem(new MenuItem("新建", (s, e) => NewFile()));

public MenuItem AddSubItem(string text)

项目说明
参数text:子菜单项显示文本
返回新建的子菜单项(无点击事件)
作用便捷添加一个只有文本的子项
var file = new MenuItem("文件");
MenuItem itemNew = file.AddSubItem("新建");
itemNew.Click += (s, e) => { /* ... */ }; // 事后补点击事件

public MenuItem AddSubItem(string text, EventHandler onClick)

项目说明
参数text:子菜单文本
onClick:点击事件处理器(可为 null)
返回新建的子菜单项
var file = new MenuItem("文件");
file.AddSubItem("打开", (s, e) => OpenFile());

public MenuItem AddSeparator()

项目说明
参数无
返回新建的分隔线子项
作用向当前项的 Items 追加一条分隔线
file.AddSubItem("保存", Save);
file.AddSeparator();               // 分隔线
file.AddSubItem("退出", Exit);

public override string ToString()

项目说明
返回分隔线返回 "(分隔线)",其他返回 Text
用途调试输出、日志

1.7 常见用法示例

单个菜单项

var item = new MenuItem("复制")
{
    ShortcutKeyDisplayString = "Ctrl+C",
    Flag = "cmd.copy",
    Tag = CopyAction
};
item.Click += (s, e) => Clipboard.SetText("Hello");

带子菜单

var fileMenu = new MenuItem("文件");
fileMenu.AddSubItem("新建", (s, e) => NewFile());
fileMenu.AddSubItem("打开", (s, e) => OpenFile());
fileMenu.AddSeparator();
fileMenu.AddSubItem("退出", (s, e) => Application.Exit());

分隔线 + 禁用项

var root = new List<MenuItem>
{
    new MenuItem("刷新", (s, e) => Refresh()),
    new MenuItem(true),                          // 分隔线
    new MenuItem("粘贴") { Enabled = false },    // 禁用项
    new MenuItem("隐藏项") { Visible = false }   // 不显示
};

二、ContextMenu 上下文菜单

2.1 作用

完全自绘的右键上下文菜单:

  • 支持多级子菜单、键盘导航、屏幕边缘自动调整位置;

  • 支持纯色背景 + 可选背景图片(可设置是否画在边框内);

  • 支持单列 / 多列布局、固定宽度;

  • 所有颜色支持 ARGB(可在属性面板通过 ArgbColorEditor 可视化编辑);

  • 弹出时会在屏幕外点击左键 / 按 ESC / 按 Enter 时自动关闭。

2.2 构造

继承自 Component,无自定义构造函数,直接用默认无参构造:

var menu = new ContextMenu();
// 可放入容器管理(例如 Form 的 components 容器)

也可以通过 Visual Studio 工具箱拖入([ToolboxItem(true)])。

2.3 公开事件

事件类型说明
MenuOpenedEventHandler菜单打开后触发
MenuClosedEventHandler菜单关闭后触发(该类默认事件,双击组件即生成)
ItemClickedEventHandler<MenuItem>某个菜单项被点击时触发,e 为被点击的 MenuItem(不是 EventArgs)
menu.MenuOpened += (s, e) => Console.WriteLine("菜单打开");
menu.MenuClosed += (s, e) => Console.WriteLine("菜单关闭");
menu.ItemClicked += (s, item) =>
{
    Console.WriteLine($"点击项:{item.Text}, Flag={item.Flag}");
    // item.Click 也会独立触发(先 Click 后 ItemClicked)
};

注意 ItemClicked 是 EventHandler<MenuItem>,其 e 直接是 MenuItem 对象,与 EventArgs 无关。

2.4 公开属性

2.4.1 外观(Category:CCon_外观)

属性类型默认说明
MenuFontFontMicrosoft YaHei, 9pt菜单字体。设置 null 会被忽略
ShowShortcutKeysbooltrue是否显示快捷键文本;false 时不绘制 ShortcutKeyDisplayString
menu.MenuFont = new Font("Segoe UI", 9.5f);
menu.ShowShortcutKeys = true;

2.4.2 颜色(Category:CCon_颜色)

全部支持 ARGB(含透明度);在属性面板中显示为色块预览,点击可弹出 ARGB 选择器(ArgbColorEditor)。

属性默认值说明
MenuBackColor(45, 45, 48)菜单背景色(当绘制图片背景时,作为铺底色)
MenuBorderColor(80, 80, 84)菜单边框色
ItemTextColor(220, 220, 220)普通菜单项文本色
ShortcutTextColor(140, 140, 140)普通菜单项快捷键文本色
HoverBackColor(62, 62, 66)悬停背景色。支持 半透明,会与下层背景(纯色或图片)Alpha 混合
HoverTextColorWhite悬停项文本色
HoverShortcutTextColorWhite悬停项快捷键文本色
DisabledTextColor(100, 100, 100)禁用项文本色
DisabledShortcutTextColor(70, 70, 70)禁用项快捷键文本色
SeparatorColor(60, 60, 64)分隔线颜色
menu.MenuBackColor = Color.FromArgb(230, 30, 30, 30);   // 半透明深灰
menu.HoverBackColor = Color.FromArgb(180, 0, 120, 215); // 半透明蓝

2.4.3 尺寸(Category:CCon_尺寸)

属性类型默认范围说明
ItemHeightint24≥12普通菜单项高度(像素)
SeparatorHeightint7≥2分隔线高度(像素)
BorderThicknessint1≥0边框粗细;0 表示无边框
LeftPaddingint10≥0菜单项文本左内边距
RightPaddingint3≥0菜单项文本右内边距
ShortcutGapint8≥0主文本与快捷键/箭头之间的最小间距
MinWidthint60≥20菜单最小宽度;仅在单列自动宽度模式下生效
FixedWidthboolfalse—true 时使用 MenuWidth 作为菜单宽度,并强制单列;false 时按内容自动计算宽度
MenuWidthint200≥20固定宽度值;仅在 FixedWidth=true 时生效
menu.ItemHeight = 28;
menu.SeparatorHeight = 8;
menu.FixedWidth = true;
menu.MenuWidth = 240;

2.4.4 分列(Category:CCon_分列)

属性类型默认说明
EnableColumnLimitboolfalse启用单列项目数限制;超限自动分列显示。FixedWidth=true 时忽略(强制单列)
MaxItemsPerColumnint8单列最多显示项目数,≥1;仅在 EnableColumnLimit=true 时生效
menu.EnableColumnLimit = true;
menu.MaxItemsPerColumn = 10;   // 超过 10 项自动分成多列

分列时,每列独立计算宽度;列与列之间无间隙(按列宽累加)。

2.4.5 图片背景(Category:CCon_图片背景)

属性类型默认说明
UseImageBackgroundboolfalse是否使用图片作为背景
ImageBackgroundImagenull背景图片
ImageBackgroundLayoutCConPlus.Enum.ImageSizeModeTile背景图片显示方式(支持 Tile 平铺 / 拉伸 / 居中 / 缩放等,依 CConPlus.GraphicsC.DrawImageInRect 的实现)
DrawImageInsideBorderbooltrue是否将图片绘制在边框内部:
true:先画边框,再在边框内侧绘制图片(图片不覆盖边框)
false:先画图片铺满客户区,再画边框(边框盖住图片边缘)
menu.UseImageBackground = true;
menu.ImageBackground = Image.FromFile("bg.png");
menu.ImageBackgroundLayout = CConPlus.Enum.ImageSizeMode.Stretch;
menu.DrawImageInsideBorder = true;

2.4.6 数据(Category:隐藏 / Browsable(false))

属性类型说明
ItemsList<MenuItem>根级菜单项集合。只读属性,但返回 List 本身,可直接 Add / Remove / Clear
IsOpenbool只读,菜单当前是否处于打开状态
LastClickedItemMenuItem只读,最近一次被点击的菜单项;从未点击或本次是自动关闭时可能为 null
menu.Items.Add(new MenuItem("复制", (s, e) => Copy()));
menu.Items.Add(MenuItem.CreateSeparator());
menu.Items.Add(new MenuItem("粘贴", (s, e) => Paste()));

if (menu.IsOpen) menu.Close();

if (menu.LastClickedItem != null)
    Console.WriteLine("上次点击了:" + menu.LastClickedItem.Text);

2.5 公开方法

public void Show(Point screenLocation)

参数类型说明
screenLocationPoint屏幕坐标(不是控件坐标)
返回说明
void无返回值
项目说明
作用在指定屏幕坐标弹出菜单(未指定 owner)
特殊行为① 会先调用 Close() 关闭之前打开的菜单;② 会重置点击状态(_lastClickedIndex = -1、_lastClickedItem = null);③ 若无任何可见根项,则直接返回不弹出;④ 自动调整位置防止超出屏幕工作区
// 右键菜单场景:将鼠标客户区坐标转为屏幕坐标
void panel_MouseUp(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Right)
        menu.Show(panel1.PointToScreen(e.Location));
}

public void Show(Control owner, Point screenLocation)

参数类型说明
ownerControl所有者控件;用于判断菜单应在哪个屏幕上工作(Screen.FromControl(owner))。可为 null(等价于单参数重载)
screenLocationPoint屏幕坐标
返回说明
void无返回值
项目说明
作用同单参数重载,但通过 owner 确定屏幕范围,多显示器场景下更准确
特殊行为与单参数版本一致;此外会调用 USER32.SetForegroundWindow 和 Activate() 确保弹窗获得焦点
menu.Show(this, this.PointToScreen(e.Location));

位置自动调整逻辑:

  • 若 x + 菜单宽度 > 屏幕右边缘,则 x = 右边缘 - 宽度

  • 若 y + 菜单高度 > 屏幕下边缘,则 y = 下边缘 - 高度

  • 最后兜底,保证 x、y 不超出屏幕工作区左/上边界

public void Close()

项目说明
参数无
返回void
作用关闭当前弹出的菜单以及所有层级的子菜单
副作用① 若本轮未通过点击触发关闭(即自动关闭、外部调用、ESC 等),会清空 _lastClickedIndex = -1、_lastClickedItem = null;② 若本轮已通过点击触发关闭(即点击项后由 NotifyItemClicked 关闭),则保留索引与项;③ 触发 MenuClosed
幂等_popup == null 时直接返回,无副作用
menu.Close();

程序退出、切换窗体或用户点击外部区域时应显式调用 Close()(内部全局鼠标监视器也会自动触发关闭,但显式调用更保险)。

public int GetClickedItemIndex()

项目说明
参数无
返回int:最近一次被点击的菜单项索引;未点击过或本次为自动关闭时返回 -1
索引规则深度优先前序,从 0 开始,依次是「父项 → 其子项(递归)→ 下一父项」

索引示例:

根菜单:
  A (0)             ← 索引 0
    A1 (1)          ← 索引 1
    A2 (2)          ← 索引 2
      A2a (3)       ← 索引 3
  B (4)             ← 索引 4
    B1 (5)          ← 索引 5
menu.ItemClicked += (s, item) =>
{
    int idx = menu.GetClickedItemIndex();
    Console.WriteLine($"点击项 {item.Text} 的索引:{idx}");
};

public MenuItem GetItemByIndex(int index)

参数类型说明
indexint目标索引(使用与 GetClickedItemIndex 相同的编号规则)
返回说明
MenuItem对应菜单项;index < 0 或越界时返回 null
MenuItem item = menu.GetItemByIndex(3);
if (item != null) Console.WriteLine(item.Text);

public int IndexOf(MenuItem item)

参数类型说明
itemMenuItem要查找的菜单项(按引用比较)
返回说明
int该菜单项的索引;item 为 null 或未找到时返回 -1
int idx = menu.IndexOf(myMenuItem);   // 未找到返回 -1

2.6 隐藏的继承成员

ContextMenu 继承自 Component,不是 Control,所以没有 BackColor、Font 等属性;外观通过上面列出的专用属性控制。Dispose 由 Component 提供,内部已重写并会关闭菜单、释放内部字体。


三、组合调用示例

示例 1:最简菜单

public partial class Form1 : Form
{
    private ContextMenu _menu;

    public Form1()
    {
        InitializeComponent();

        _menu = new ContextMenu();
        _menu.Items.Add(new MenuItem("打开", (s, e) => MessageBox.Show("打开")));
        _menu.Items.Add(new MenuItem("保存", (s, e) => MessageBox.Show("保存")));
        _menu.Items.Add(MenuItem.CreateSeparator());
        _menu.Items.Add(new MenuItem("退出", (s, e) => Close()));

        // 在某个控件(或窗体)上绑定右键事件
        panel1.MouseUp += Panel1_MouseUp;
        MouseUp += Panel1_MouseUp;
    }

    private void Panel1_MouseUp(object sender, MouseEventArgs e)
    {
        if (e.Button != MouseButtons.Right) return;
        Control c = sender as Control;
        _menu.Show(c, c.PointToScreen(e.Location));
    }
}

示例 2:多级子菜单

var fileMenu = new MenuItem("文件");
fileMenu.AddSubItem("新建", (s, e) => NewFile());
fileMenu.AddSubItem("打开", (s, e) => OpenFile());

var recent = fileMenu.AddSubItem("最近打开");   // 只有文本
recent.AddSubItem("a.txt", (s, e) => OpenFile("a.txt"));
recent.AddSubItem("b.txt", (s, e) => OpenFile("b.txt"));

fileMenu.AddSeparator();
fileMenu.AddSubItem("退出", (s, e) => Application.Exit());

_menu.Items.Add(fileMenu);

示例 3:带背景图 + ARGB 悬停色

var menu = new ContextMenu();
menu.MenuFont = new Font("Microsoft YaHei", 10F);
menu.ItemHeight = 28;
menu.MenuBackColor = Color.FromArgb(240, 30, 30, 34);
menu.HoverBackColor = Color.FromArgb(180, 0, 120, 215);
menu.MenuBorderColor = Color.FromArgb(255, 80, 80, 84);
menu.UseImageBackground = true;
menu.ImageBackground = Image.FromFile("bg.png");
menu.ImageBackgroundLayout = CConPlus.Enum.ImageSizeMode.Tile;
menu.DrawImageInsideBorder = true;

示例 4:分列显示(超长菜单)

var menu = new ContextMenu();
menu.EnableColumnLimit = true;
menu.MaxItemsPerColumn = 8;   // 每列最多 8 项,超出自动分列

for (int i = 1; i <= 25; i++)
{
    int n = i;
    menu.Items.Add(new MenuItem("选项 " + n, (s, e) => MessageBox.Show("选中 " + n)));
}

示例 5:处理点击与索引

menu.ItemClicked += (s, item) =>
{
    int idx = menu.GetClickedItemIndex();
    if (item.Flag == "cmd.exit") Close();
    else MessageBox.Show($"item={item.Text} 索引={idx} flag={item.Flag}");
};

// 事后根据点击项反查索引:
MenuItem m = menu.GetItemByIndex(menu.GetClickedItemIndex());

示例 6:ClickableWithSubMenu 让父项也能被点击

var tools = new MenuItem("工具");
tools.ClickableWithSubMenu = true;       // 点击父项本身也会触发 Click
tools.Click += (s, e) => MessageBox.Show("直接点击了【工具】");

tools.AddSubItem("选项", (s, e) => MessageBox.Show("选项"));
tools.AddSubItem("扩展", (s, e) => MessageBox.Show("扩展"));

menu.Items.Add(tools);
  • ClickableWithSubMenu = false(默认):点击父项只展开子菜单,不触发 Click。

  • ClickableWithSubMenu = true:点击父项同时触发展开和 Click。

示例 7:禁用 / 隐藏 / 分隔线

var paste = new MenuItem("粘贴")
{
    Enabled = false,                   // 禁用(灰显,点击无效)
    ShortcutKeyDisplayString = "Ctrl+V"
};
var hidden = new MenuItem("隐藏项") { Visible = false };  // 完全不显示
var sep = MenuItem.CreateSeparator();

menu.Items.Add(new MenuItem("复制", (s, e) => Copy()));
menu.Items.Add(paste);
menu.Items.Add(hidden);
menu.Items.Add(sep);
menu.Items.Add(new MenuItem("全选", (s, e) => SelectAll()));

四、公开成员速查表

MenuItem

成员类型说明
MenuItem() / MenuItem(string) / MenuItem(string, EventHandler) / MenuItem(bool)构造函数4 个重载
CreateSeparator()static 方法创建分隔线
PerformClick()方法手动触发 Click
AddSubItem(MenuItem)方法添加子项并返回
AddSubItem(string)方法添加文本子项并返回
AddSubItem(string, EventHandler)方法添加带点击事件的子项并返回
AddSeparator()方法添加分隔线子项并返回
ToString()override 方法调试文本
Text / ShortcutKeyDisplayString / Flag属性文本类
Enabled / Visible / IsSeparator / ClickableWithSubMenu属性行为开关
Items属性(只读引用)子项集合
HasSubMenu / IsClickable属性(只读)状态判定
Tag属性自定义数据
Click事件点击时触发

ContextMenu

成员类型说明
Show(Point)方法按屏幕坐标弹出
Show(Control, Point)方法按屏幕坐标弹出(指定 owner)
Close()方法关闭所有层级的菜单
GetClickedItemIndex()方法返回最近点击项索引(-1 表示未点击/自动关闭)
GetItemByIndex(int)方法按索引取项
IndexOf(MenuItem)方法按项取索引(-1 表示未找到)
MenuFont / ShowShortcutKeys属性外观
MenuBackColor / MenuBorderColor / ItemTextColor / ShortcutTextColor / HoverBackColor / HoverTextColor / HoverShortcutTextColor / DisabledTextColor / DisabledShortcutTextColor / SeparatorColor属性(ARGB)颜色
ItemHeight / SeparatorHeight / BorderThickness / LeftPadding / RightPadding / ShortcutGap / MinWidth / FixedWidth / MenuWidth属性尺寸
EnableColumnLimit / MaxItemsPerColumn属性分列
UseImageBackground / ImageBackground / ImageBackgroundLayout / DrawImageInsideBorder属性图片背景
Items / IsOpen / LastClickedItem属性(只读引用 / 只读)数据
MenuOpened / MenuClosed / ItemClicked事件生命周期与点击

五、注意事项

  1. 坐标必须是屏幕坐标。Show(Point) / Show(Control, Point) 的参数是屏幕坐标,而不是控件客户区坐标。请使用 control.PointToScreen(e.Location) 转换。

  2. Show 会先关闭旧菜单。如果你连续调用 Show,之前打开的菜单会被自动关闭并触发 MenuClosed。

  3. 无可见项不会弹出。Show 会先调用 HasVisibleItems(_items) 检查根级是否有可见项,若全不可见则直接返回,MenuOpened 不会触发。

  4. ItemClicked 与 MenuItem.Click 的触发顺序:

    • 先触发被点击 MenuItem 自身的 Click 事件

    • 再触发 ContextMenu.ItemClicked 事件(e 是 MenuItem)

  5. 索引与 LastClickedItem 的保留/清空规则:

    • 通过点击项 → 内部调用 NotifyItemClicked → 记录索引/项 → 关闭菜单时保留

    • 通过 ESC / 点击外部 / 显式 Close() 关闭 → 清空(-1 / null)

    • 因此如果你需要在 MenuClosed 中判断用户到底有没有点击某项,可以看 GetClickedItemIndex() >= 0 或 LastClickedItem != null。

  6. 索引规则是深度优先前序。GetClickedItemIndex()、GetItemByIndex(int)、IndexOf(MenuItem) 三者共用同一套编号规则,可互相一致。

  7. HasSubMenu 判断的是"至少有一个可见子项"。父项若只有不可见的子项(Visible=false),则不绘制箭头、不可展开,IsClickable 也会按无子菜单处理。

  8. ClickableWithSubMenu:

    • false(默认):有子菜单的项点击只展开,不触发 Click;

    • true:有子菜单的项点击同时展开并触发 Click。

  9. 键盘操作(自动开启,无需设置):

    • ↑ / ↓:在当前层移动活动项(跳过不可见、禁用、分隔线)

    • →:展开子菜单

    • ←:收起当前层子菜单

    • Enter:点击当前活动项(若带子菜单则展开)

    • Esc:关闭整个菜单链

  10. 子菜单展开有 180ms 悬停延迟(避免鼠标经过父项时误开)。

  11. FixedWidth = true 时忽略 EnableColumnLimit 与 MaxItemsPerColumn,强制单列显示。

  12. MinWidth 仅在单列自动宽度模式下生效。多列时每列独立按内容测量,MinWidth 不影响。

  13. HoverBackColor 支持 Alpha,绘制时使用 CompositingMode.SourceOver 与下层内容(纯色 / 图片)混合。

  14. DrawImageInsideBorder 语义:

    • true(默认):边框 → 边框内侧图片 → 菜单项

    • false:图片铺满整个客户区 → 边框盖住边缘 → 菜单项

  15. ContextMenu 不是 Control,不能直接放到窗体上作为子控件;它是 Component,通过 menu.Show(...) 使用。设计器中可放入 components 容器以便自动释放。

  16. Dispose 时会自动关闭菜单并释放内部 MenuFont(不释放 SystemFonts 共享实例),因此请通过 menu.Dispose() 或 using (var menu = new ContextMenu()) { ... } 管理生命周期。

  17. 弹窗会用 SetForegroundWindow + Activate 获取焦点(依赖 CConPlus.Windows.API.USER32),保证键盘事件能被弹窗捕获。

  18. ImageBackgroundLayout 的类型是 CConPlus.Enum.ImageSizeMode,需要引用 CConPlus 程序集;DrawImageInRect 来自 CConPlus.GraphicsC。如果你的项目没有 CConPlus,需要在工程中添加引用。

转载请注明出处。

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

相关文章

已经实现的一些算法

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

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

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

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

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

图片框PictureBox 控件调用文档

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

蚂蚁线AntLine 控件调用文档

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