如何管理带分隔符的动态菜单?
How to manage a dynamic menu with separators?
我必须在表单上开发一个简单的菜单,例如:
- 文件
- 选项 A
- 选项 B
- --------(分隔符 1)
- 选项 C
- 选项 D
- --------(分隔符 2)
- 选项 E
每个条目都存储在数据库中,是否可见取决于连接的用户权限
例如,用户 "J.Doe" 将看不到选项 C 和 D
我的问题是:如何动态避免菜单显示 2 个分隔符,因为显然选项 B 和 E 之间只需要一个分隔符?
如果满足以下三个条件,只需添加分隔符:
- 至少已有一项菜单项。
- 上一个菜单项不是分隔符。
- 在当前菜单项之后至少还要添加一个菜单项。
这应该不会太难。尝试按照此规范编写代码,如果您 运行 遇到麻烦,请来这里再次询问更具体的编码问题。
更新:看到这里提出的解决方案,它们都是针对您的具体问题量身定制的,我将继续向您展示我将如何解决一般问题适用于 any 菜单配置的方法:
static void DynamicallySetMenuItems(MenuItem menu, UserRole role)
{
var menuItems = GetMenuItems(role);
var previous = menuItems.FirstOrDefault();
if (previous == null)
return;
if (!IsSeparator(previous))
{
menu.MenuItems.Add(previous);
}
foreach (var current in menuItems.Skip(1))
{
if (!IsSeparator(current) ||
!IsSeparator(previous))
{
menu.MenuItems.Add(previous);
}
previous = current;
}
if (IsSeparator(previous))
{
menu.MenuItems.Remove(previous);
}
}
static bool IsSeparator(MenuItem menu)
=> menu.Text == "-";
您只需即时构建菜单,如下所示:
var myMenu = new ContextMenuStrip(); // works also with tool strip menus, main menu, etc...
int m = 0;
if( /* has option A */ )
{
myMenu.Items.Add("Option A");
myMenu.Items[m++].Click += OptionA_Click;
}
if( /* has option B */ )
{
myMenu.Items.Add("Option B");
myMenu.Items[m++].Click += OptionB_Click;
}
if( /* has option C or D */ )
{
myMenu.Items.Add(new ToolStripSeparator());
m++;
}
if( /* has option C */ )
{
myMenu.Items.Add("Option C");
myMenu.Items[m++].Click += OptionC_Click;
}
if( /* has option D */ )
{
myMenu.Items.Add("Option D");
myMenu.Items[m++].Click += OptionD_Click;
}
if( /* has option E */ )
{
myMenu.Items.Add(new ToolStripSeparator());
myMenu.Items.Add("Option E");
myMenu.Items[++m].Click += OptionE_Click;
}
我必须在表单上开发一个简单的菜单,例如:
- 文件
- 选项 A
- 选项 B
- --------(分隔符 1)
- 选项 C
- 选项 D
- --------(分隔符 2)
- 选项 E
每个条目都存储在数据库中,是否可见取决于连接的用户权限
例如,用户 "J.Doe" 将看不到选项 C 和 D
我的问题是:如何动态避免菜单显示 2 个分隔符,因为显然选项 B 和 E 之间只需要一个分隔符?
如果满足以下三个条件,只需添加分隔符:
- 至少已有一项菜单项。
- 上一个菜单项不是分隔符。
- 在当前菜单项之后至少还要添加一个菜单项。
这应该不会太难。尝试按照此规范编写代码,如果您 运行 遇到麻烦,请来这里再次询问更具体的编码问题。
更新:看到这里提出的解决方案,它们都是针对您的具体问题量身定制的,我将继续向您展示我将如何解决一般问题适用于 any 菜单配置的方法:
static void DynamicallySetMenuItems(MenuItem menu, UserRole role)
{
var menuItems = GetMenuItems(role);
var previous = menuItems.FirstOrDefault();
if (previous == null)
return;
if (!IsSeparator(previous))
{
menu.MenuItems.Add(previous);
}
foreach (var current in menuItems.Skip(1))
{
if (!IsSeparator(current) ||
!IsSeparator(previous))
{
menu.MenuItems.Add(previous);
}
previous = current;
}
if (IsSeparator(previous))
{
menu.MenuItems.Remove(previous);
}
}
static bool IsSeparator(MenuItem menu)
=> menu.Text == "-";
您只需即时构建菜单,如下所示:
var myMenu = new ContextMenuStrip(); // works also with tool strip menus, main menu, etc...
int m = 0;
if( /* has option A */ )
{
myMenu.Items.Add("Option A");
myMenu.Items[m++].Click += OptionA_Click;
}
if( /* has option B */ )
{
myMenu.Items.Add("Option B");
myMenu.Items[m++].Click += OptionB_Click;
}
if( /* has option C or D */ )
{
myMenu.Items.Add(new ToolStripSeparator());
m++;
}
if( /* has option C */ )
{
myMenu.Items.Add("Option C");
myMenu.Items[m++].Click += OptionC_Click;
}
if( /* has option D */ )
{
myMenu.Items.Add("Option D");
myMenu.Items[m++].Click += OptionD_Click;
}
if( /* has option E */ )
{
myMenu.Items.Add(new ToolStripSeparator());
myMenu.Items.Add("Option E");
myMenu.Items[++m].Click += OptionE_Click;
}