【问题标题】:How to enable ALL controls on a form?如何启用表单上的所有控件?
【发布时间】:2011-08-24 21:57:38
【问题描述】:

目前我在启动时禁用了大部分表单控件,因为在加载文件之前您无法使用它们。但是,一旦加载了文件,控件就会启用。

我正在使用绑定,但我认为它们不是一个好的解决方案。一方面,这是不必要的复杂性。其次,您不能对所有内容都使用绑定。例如,MenuStrip 项不能将其 Enabled 属性绑定到 fileLoaded 属性。只有整个菜单可以而且我不想在启动时禁用整个菜单,只有对文件进行操作的某些菜单操作。

我真的只是在寻找一种启用一切的方法。大多数人在被问到时会这样回答:

foreach (Control c in Controls)
{
    c.Enabled = true;
}

但是,这不适用于在其他控件(如面板或自定义控件)中启用 MenuStrip 项或控件。因此它不会在容器中启用滚动条。

我想我可以使用该行并手动启用其他所有功能,但我总是可以手动启用所有功能。我正在寻找一种自动启用一切的方法。

【问题讨论】:

  • 最初是如何禁用这些元素的?也许您可以跟踪列表中禁用的内容,然后重新启用该列表中的所有元素(并清除它)。
  • 它们在表单设计器中被禁用。大多数应用程序的工具在没有加载文件的情况下无法使用,因此默认情况下它们被禁用。

标签: c# winforms loops


【解决方案1】:

递归

private void enableControls(Control.ControlCollection Controls)
{
    foreach (Control c in Controls)
    {
        c.Enabled = true;
        if (c is MenuStrip)
        {
           foreach(var item in ((MenuStrip)c).Items)
           { 
              item.Enabled = true;
           }
        }
        if (c.ControlCollection.Count > 0)
            enableControls(c.Controls);

    }
}

编辑

应该一直检查控件 Collection 计数而不是 HasControls 这是 Web 控件

【讨论】:

  • 谢谢,这很好用。但是,它仍然不启用 MenuStrip 项。我想我可以手动启用它们,但我想知道是否有办法将它们包含在这个循环中?
  • 还是不行=P 通过调试发现它只是启用了按钮而不是子菜单。例如,如果您有菜单项 File 和 Edit,它只会启用这两个,而不是菜单项 New、Save、Undo 和 Redo。此外,必须将 item 强制转换为 ToolStripMenuItem,并且 c.ControlCollection.Count > 0 应替换为 c.HasChildren。
  • 这行得通:pastebin.com/dYmyunaV 但如果有更好的方法,它可能有点矫枉过正或不必要。
  • 不要太长而不是在面板中拥有所有控件?启用/禁用面板只是一行代码。
【解决方案2】:

将所有控件放在一个面板中;

panel.enable = false -> 面板中的所有控件都将被禁用 panel.enable = true -> 面板中的所有控件都将被启用(如果它们默认启用,请尽快用启用的控件填充您的面板,让您的面板禁用,这样您的控件也将被禁用。启用面板后,您的控件将被启用)

【讨论】:

    【解决方案3】:

    对于 menustrip 项目,您可以递归地执行此操作,这非常简单。 只需将 item.Enabled 标志设置为 true 或 false。

    您可以使用我的类,它只是几行代码,易于使用。您还可以创建一个搜索功能并只传递要禁用的名称。 享受:

    namespace Test_MenuItemIteration
    {
        using System.Collections.Generic;
        using System.Windows.Forms;
    
        public static class GetAllMenuStripItems
        {
            #region Methods
    
            /// <summary>
            /// Gets a list of all ToolStripMenuItems
            /// </summary>
            /// <param name="menuStrip">The menu strip control</param>
            /// <returns>List of all ToolStripMenuItems</returns>
            public static List<ToolStripMenuItem> GetItems(MenuStrip menuStrip)
            {
                List<ToolStripMenuItem> myItems = new List<ToolStripMenuItem>();
                foreach (ToolStripMenuItem i in menuStrip.Items)
                {
                    GetMenuItems(i, myItems);
                }
                return myItems;
            }
    
            /// <summary>
            /// Gets the menu items.
            /// </summary>
            /// <param name="item">The item.</param>
            /// <param name="items">The items.</param>
            private static void GetMenuItems(ToolStripMenuItem item, List<ToolStripMenuItem> items)
            {
                items.Add(item);
                foreach (ToolStripItem i in item.DropDownItems)
                {
                    if (i is ToolStripMenuItem)
                    {
                        GetMenuItems((ToolStripMenuItem)i, items);
                    }
                }
            }
    
            #endregion Methods
        }
    }
    

    在您的应用中使用:

    List<ToolStripMenuItem> myItems = GetAllMenuStripItems.GetItems(this.menuStrip1);
    foreach (var item in myItems)
    {
        MessageBox.Show(item.Text);
        item.Enabled = false;
    }
    

    【讨论】:

      【解决方案4】:

      这样做:

      var Enable = (Control c) =>
                   {
                       c.Enabled = true;
                       if(c.Controls != null)
                           foreach(Control c2 in c.Controls)
                               Enable(c2);
                   }
      
      Enable(YourForm);
      

      【讨论】:

      • @msarchet:不,它没有,它是递归的
      • 这个没问题。请记住,它将查找所有控件。过滤它们可能很有趣。 Tag 属性可能会有所帮助。例如,当 Tag != null 时,您检查控件本身和所有拥有的控件,如果没有,则跳过。
      • 为什么需要if(c.Controls != null)?如果它为 null,foreach 将不会做任何事情
      【解决方案5】:

      递归迭代您的菜单对于禁用菜单中的每个项目是必要的。但是,对于所有表单控件,有一个更简单的解决方案——将它们嵌入到跨越整个表单的面板中,并在 VS Designer 中禁用该表单。当您的用户选择文件时,启用面板和中提琴!不需要额外的递归(或开销)。

      如果您仍想走递归路线,我将更改 Enable 方法,首先将其重命名为 ChangeEnabledState,其次,我将使用一个布尔参数,允许您使用它分配给 Enabled 属性。这样,您可以根据需要启用/禁用控件。但是请记住,您需要添加一个检查,以查看控件是否是按钮(或您用来打开 OpenFileDialog 的任何控件)是否在禁用操作中被跳过。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-11-06
        • 1970-01-01
        • 1970-01-01
        • 2015-06-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多