目前我在启动时禁用了大多数表单控件,因为在加载文件之前无法使用它们。但是,一旦文件被加载,控件就应该被启用。
我使用绑定,但我不认为这是一个很好的解决方案。首先,这是不必要的复杂性。其次,不能对所有事情都使用绑定。例如,菜单条项不能将其Enabled属性绑定到fileLoaded属性。只有整个菜单可以并且我不想在启动时禁用整个菜单,只有在文件上操作的某些菜单操作才能禁用。
我真的只是在寻找一种方法来启用一切。当被问及这个问题时,大多数人会这样回答:
foreach (Control c in Controls)
{
c.Enabled = true;
}
但是,这不适用于在其他控件(如Panel或自定义控件)中启用MenuStrip项或控件。因此,它不会在容器内启用滚动条。
我想我可以使用这一行并手动启用其他所有内容,但是我可以总是使用手动启用所有内容。我正在寻找一种方法来自动启用一切。
递归
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);
}
}
编辑
应该检查控件集合计数而不是HasControls,这是Webcontrols
将所有控件放到一个面板中;
面板。Enable = false ->面板中的所有控件将被禁用面板。启用= true ->面板中的所有控件将被启用(如果它们是默认启用的,请在面板中填充启用的控件,让您的面板禁用,以便您的控件也将被禁用)。启用面板后,您的控件将被启用)
对于菜单栏项,您可以递归地执行,这非常简单。只需将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;
}
这样做:
var Enable = (Control c) =>
{
c.Enabled = true;
if(c.Controls != null)
foreach(Control c2 in c.Controls)
Enable(c2);
}
Enable(YourForm);
在菜单上递归迭代是禁用菜单中的每个项所必需的。然而,对于所有的表单控件,有一个更简单的解决方案——将它们嵌入到一个横跨整个表单的面板中,并在VS设计器中禁用表单。当你的用户选择一个文件,启用面板和viola!不需要额外的递归(或开销)。
如果你仍然想走递归路线,我会改变Enable方法,首先将其重命名为ChangeEnabledState
,其次,我将一个bool参数,允许你使用分配给Enabled
属性。这样,您就可以根据需要启用/禁用控件。但是,请记住,您需要添加一个检查,以查看控件是否是在禁用操作中跳过的按钮(或用于打开OpenFileDialog的任何控件)。