C# WinForms中是否有Delphi TAction/TActionList/TImageList等价组件?
WinForms 实现类似 Delphi TAction 的操作管理机制
WinForms 没有内置和 Delphi TAction 完全一致的框架,但可以通过自定义封装实现相同的操作同步管理效果,以下是具体实现方案:
1. 自定义 Action 基类
封装一个包含核心属性和事件的 Action 基类,统一管理操作的状态与行为:
public class ActionBase { private bool _enabled = true; private bool _visible = true; private string _text; private int _imageIndex = -1; private Keys _shortcutKeys; public event EventHandler Execute; public event EventHandler Changed; public bool Enabled { get => _enabled; set { if (_enabled != value) { _enabled = value; OnChanged(); } } } public bool Visible { get => _visible; set { if (_visible != value) { _visible = value; OnChanged(); } } } public string Text { get => _text; set { if (_text != value) { _text = value; OnChanged(); } } } public int ImageIndex { get => _imageIndex; set { if (_imageIndex != value) { _imageIndex = value; OnChanged(); } } } public Keys ShortcutKeys { get => _shortcutKeys; set { if (_shortcutKeys != value) { _shortcutKeys = value; OnChanged(); } } } protected virtual void OnChanged() { Changed?.Invoke(this, EventArgs.Empty); } public void PerformExecute() { Execute?.Invoke(this, EventArgs.Empty); } }
2. 绑定控件与 Action
写扩展方法实现控件与 Action 的绑定,自动同步状态变化:
public static class ActionControlBinder { public static void BindToAction(this ToolStripMenuItem menuItem, ActionBase action) { // 初始同步状态 menuItem.Text = action.Text; menuItem.Enabled = action.Enabled; menuItem.Visible = action.Visible; menuItem.ImageIndex = action.ImageIndex; menuItem.ShortcutKeys = action.ShortcutKeys; // 绑定点击触发逻辑 menuItem.Click += (s, e) => action.PerformExecute(); // 监听Action变化,实时同步控件 action.Changed += (s, e) => { menuItem.Text = action.Text; menuItem.Enabled = action.Enabled; menuItem.Visible = action.Visible; menuItem.ImageIndex = action.ImageIndex; menuItem.ShortcutKeys = action.ShortcutKeys; }; } public static void BindToAction(this ToolStripButton toolButton, ActionBase action) { toolButton.Text = action.Text; toolButton.Enabled = action.Enabled; toolButton.Visible = action.Visible; toolButton.ImageIndex = action.ImageIndex; toolButton.Click += (s, e) => action.PerformExecute(); action.Changed += (s, e) => { toolButton.Text = action.Text; toolButton.Enabled = action.Enabled; toolButton.Visible = action.Visible; toolButton.ImageIndex = action.ImageIndex; }; } }
3. 全局快捷键处理
在窗体的ProcessCmdKey方法中实现全局快捷键触发:
private List<ActionBase> _actions = new List<ActionBase>(); protected override bool ProcessCmdKey(ref Message msg, Keys keyData) { var targetAction = _actions.FirstOrDefault(a => a.ShortcutKeys == keyData && a.Enabled); if (targetAction != null) { targetAction.PerformExecute(); return true; } return base.ProcessCmdKey(ref msg, keyData); }
4. ImageList 配合使用
WinForms 的 ImageList 可用来统一管理操作图标,只需将 MenuStrip 和 ToolStrip 的ImageList属性指向同一个实例,Action 的ImageIndex即可对应加载图标,和 Delphi 的用法逻辑一致。
使用示例
// 初始化操作 var openAction = new ActionBase { Text = "打开(&O)", ImageIndex = 0, ShortcutKeys = Keys.Control | Keys.O }; openAction.Execute += (s, e) => { /* 编写打开文件的逻辑 */ }; _actions.Add(openAction); // 绑定到菜单和工具栏按钮 openToolStripMenuItem.BindToAction(openAction); openToolButton.BindToAction(openAction); // 动态修改状态,关联控件会同步变化 openAction.Enabled = false;
内容的提问来源于stack exchange,提问作者b0bik
相关产品推荐
相关产品推荐

