65.9K
CodeProject 正在变化。 阅读更多。
Home

ActionMenuStrip<T>/OptionMenuStrip<T>: 由枚举 T 配置的通用 MenuStrips

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.89/5 (8投票s)

2006 年 4 月 21 日

CPOL

3分钟阅读

viewsIcon

47167

downloadIcon

363

使用枚举作为模板自动填充 MenuStrips。

Sample Image

引言

这些控件依赖于与 EnumGroupBox - 半自动 GroupBox 控件 相同的基本思想:通过已经在您的业务逻辑中使用的枚举来配置 GUI 元素。 相比之下,此提交生成菜单作为由 enum 作为类型参数配置的泛型类型。 ActionMenuStrip<T> 封装了一组独立的操作(单击菜单按钮),而 OptionMenuStrip<T> 表示(独占)选项的选择(选中单选按钮/复选框)。

背景

这两个控件都派生自 System.Windows.Forms.ContextMenuStrip,因此它们可以直接分配给 Control.ContextMenuStrip/ ToolStripDropDownButton.DropDown 属性,或者在更大的菜单中用作 ToolStripDropDownMenu。对于所有 enum 成员,都会创建相应的菜单项,这些菜单项在内部由一个名称标识,该名称由一个可选的公共基本名称和枚举成员名称组成。可以指定零值的成员是否构成有效选项,或者是否将被忽略。可以排除达到或高于某个值(即“Last”或“All”)的枚举成员。

菜单项的文本要么是枚举成员名称本身,要么可以传递一个 string 数组,这允许本地化或使用加速键。第三种选择是分配一个委托,该委托返回项目的文本。

ocActionMenuStrip<T>

它的公共接口如下所示(删除了次要和重载的成员)

public class ocActionMenuStrip<T> : ContextMenuStrip, 
             INotifyPropertyChanged where T : struct
{
    public event EventHandler ActionClicked
    
    public ocActionMenuStrip()
    
    public delegate string GetActionMenuText(T item)
    public GetActionMenuText MenuTexts { set; }
    
    public T ActionEnabled { get; set; }
    public T ActionVisible { get; set; }
    
    public T Action { get; set; }
    public ToolStripItemCollection ActionItems { get; }

    public ToolStripItemCollection ActionAddItems(
           string baseItemName, bool includeZero, 
           T excludeAtMember, string[] menutext)
}

通过 ActionEnabled/ActionVisible 属性,可以禁用/隐藏各个菜单项(即在 Opening 事件中)。 enum T 必须是按位(标记)的才能使用这些功能。使用基类的 Items 属性,可以添加其他 ToolStripMenuItem,而不会影响功能。在这种情况下,ActionItems 属性返回派生类维护的项目子集,否则它等于 Items 属性。

ocOptionMenuStrip<T>

public class ocOptionMenuStrip<T> : ContextMenuStrip, 
                   INotifyPropertyChanged where T : struct
{
    public event EventHandler OptionChanged
    public event PropertyChangedEventHandler PropertyChanged

    public ocOptionMenuStrip()

    public delegate string GetOptionMenuText(T item)
    public GetOptionMenuText MenuTexts { set; }

    public bool OptionExclusive { get; set; }
    public bool CancelClosingOnCheck { get; set; }
    public T OptionEnabled { get; set; }
    public T OptionVisible { get; set; }
    
    public T Option { get; set; }
    public T OptionMember { get; }
    public ToolStripItemCollection OptionItems { get; }

    public ToolStripItemCollection OptionAddItems( 
           string baseItemName, bool includeZero, 
           T excludeAtMember, string[] menutext)
}

OptionExclusive 属性指定菜单是设置为独占检查还是单独检查项目。 独占菜单使用单选按钮呈现,单独的菜单使用标准复选标记图像。 如果设置了 CancelClosingOnCheck 属性,则在选中项目时菜单保持打开状态。 INotifyPropertyChanged 接口的实现允许将 Option 属性数据绑定到 UserSettingsOptionMember 属性标识导致个人菜单上次更改的枚举成员。

使用代码

由于没有设计时支持(我根本不知道如何使用通用控件来实现这一点),因此所有声明都必须手工编码。 这里显示了一个示例,该示例配置了一个使用枚举名称、排除零和最后一个成员的独占选项菜单

[Flags]
private enum MyEnum {none = 0, first = 1, 
                     second = 2, third = 4, all = 7}
private ocOptionMenuStrip<MyEnum> oms;

    oms = new ocOptionMenuStrip<MyEnum>();
    oms.MenuTexts = delegate(MyEnum item)
    { 
        return (item == MyEnum.first) ? "Special First" : null ;
    }
    oms.OptionAddItems(null, false, MyEnum.all);
    oms.OptionEnabled = MyEnum.all & ~MyEnum.second;
    oms.OptionChanged += this.oms_OptionChanged;

void oms_OptionChanged(object sender, EventArgs e)
{
    switch (oms.Option)
    {
        case MyEnum.first:
            // ...
    }
}

包含的两个演示项目显示了大多数可用的可能性。

关注点

  • 如何使用通用控件实现设计时支持?
  • 您的评论和建议。

历史

  • 2005 年 12 月:OptionMenuStrip 发布在 Planet Source Code 上。
  • 2006 年 4 月:在发现 Peter Schlang 的文章后,在我的新最喜欢的网站上进行了修订和重新发布。
  • 1.0 版,2006 年 6 月 7 日th
    • 使用参数重载了 XXXAddItems 方法以排除成员。
    • 现在使用委托来设置菜单文本。
    • 错误修复:无法启用包含的零成员。

    OptionMenuStrip:

    • 之前的 OptionBitwise 变为具有相反功能的 OptionExclusive
    • OptionMember 标识更改的原因。
    • 独占菜单使用单选按钮图像绘制。
© . All rights reserved.