【问题标题】:Is there a way to make A ToolStripMenuItem shared between Menus and ToolBars?有没有办法让 A ToolStripMenuItem 在菜单和工具栏之间共享?
【发布时间】:2010-11-30 16:46:43
【问题描述】:

我正在使用 Winforms 将旧的 VB6 项目移植到 C#。原始版本使用 DataDynamic 的 ActiveBar 套件来同时管理对工具栏、菜单和快捷功能区中的多个项目的更改。所有旧代码都必须更改在多个菜单、工具栏和上下文菜单之间共享的项目的文本,即更改“工具”对象的“标题”属性。

我觉得 .NET 必须有某种方式在各种容器之间共享ToolStripItems,但它看起来不像。我错过了什么吗?

目前,我已经多次提出各种想法,从在 ToolStripMenuItem 对象上实现 Clone 扩展方法到让我的表单跟踪每个可共享对象。当我意识到更新本地副本不会更新其他副本时,那失败了(我必须添加复杂的更新事件,这比简单地手动打开和关闭每个项目要多工作)。我考虑过创建一些基于其标签更新所有项目的方法。这似乎也很不可行。

在类似情况下,你们都使用了哪些技术?

【问题讨论】:

    标签: .net winforms vb6-migration toolstrip menustrip


    【解决方案1】:

    嗯,这实际上是 .Net GUI 构建库令人讨厌的限制之一

    一种常见的解决方法是动态管理您的菜单,在它们打开时向它们添加项目。从用户体验的角度来看,丑陋但非常无缝。 诀窍是使用以下 UI 设计规范:菜单从不同时显示,因此您可以热交换项目

    private void myContextMenuStrip_Opening(object sender, CancelEventArgs e)
    {
        myContextMenuStrip.Items.Insert(3, myToolStripMenuItem);
    }  
    

    然后使用标志和代码逻辑,您将能够知道,随着菜单/工具栏/上下文菜单打开,它应该显示哪些项目。

    【讨论】:

    • “菜单从不同时显示”并不完全正确,因为我们都有 ToolbarMenuContextMenu 分类。
    【解决方案2】:

    我最终实现了一个SharedMenuItem,其职责是注册和更新需要更改的 UI 元素。上下文菜单的不同之处足以保证有自己的处理程序。

    我没有更新所有 MenuItems,而是更新了 SharedMenuItem,然后它负责其他更改。

    [编辑] 代码(添加其他属性很简单/甚至可以自动生成):

    public class SharedMenuItem
    {
        bool enabled = false;
        public bool Enabled
        {
            get { return enabled; }
            set
            {
                enabled = value;
                foreach (var member in members)
                {
                    member.Enabled = value;
                }
            }
        }
    
        bool visible;
        public bool Visible
        {
            get { return visible; }
            set
            {
                visible = value;
                foreach (var member in members)
                {
                    member.Visible = visible;
                }
            }
        }
    
        string text;
        public string Text
        {
            get { return text; }
            set
            {
                text = value;
                foreach (var member in members)
                {
                    member.Text = text;
                }
            }
        }
    
        string toolTipText = "";
        public string ToolTipText
        {
            get { return toolTipText; }
            set
            {
                toolTipText = value;
                foreach (var member in members)
                {
                    member.ToolTipText = toolTipText;
                }
            }
        }
    
        private List<ToolStripItem> members = new List<ToolStripItem>();
    
        public void Remove(ToolStripItem member)
        {
            members.Remove(member);
        }
    
        public void Add(ToolStripItem member)
        {
            members.Add(member);
        }
    
        public SharedMenuItem(string text)
        {
            this.text = text;
        }
    }
    

    【讨论】:

    • 但是,从设计的角度来看,从技术上讲,不同菜单中的项目 - 更何况同时显示,在你的情况下确实是不同的项目,尽管最终指向相同的操作。跨度>
    • 是的,它们是不同的项目,但它们需要始终共享一组属性(完美的“观察者”模式机会,类似于是)。
    猜你喜欢
    • 2023-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-27
    相关资源
    最近更新 更多