我想显示一个上下文菜单,其中菜单项是排列在网格中的图像。但是,当我在菜单的 ToolStripDropDown 中将 LayoutStyle
设置为 ToolStripLayoutStyle.Table
时,如果创建了新的 ToolStripDropDown 对象,它只会提供菜单项的网格布局。
我的问题是我可以为子菜单创建并分配一个新的 ToolStripDropDown,但不能为 ContextMenuStrip 创建和分配一个新的 ToolStripDropDown,因为它是 ToolStripDropDown。
以下代码演示了该问题。它将显示一个包含颜色样本图像的上下文菜单,并且还有两个具有相同图像的子菜单。所有三个菜单的 LayoutStyle
属性均设置为 ToolStripLayoutStyle.Table
,但只有一个菜单实际上会显示为网格。
private void FillDropDown(ToolStripDropDown drop_down)
{
// Set the drop down to a 2 column table layout
drop_down.LayoutStyle = ToolStripLayoutStyle.Table;
TableLayoutSettings table_layout_settings = (TableLayoutSettings)drop_down.LayoutSettings;
table_layout_settings.ColumnCount = 2;
// Fill the menu with some colour swatches
Color[] colours = { Color.Red, Color.Orange, Color.Yellow, Color.Green, Color.Blue, Color.Purple };
foreach (Color colour in colours) {
ToolStripMenuItem item = new ToolStripMenuItem();
Bitmap swatch = new Bitmap(64, 64);
using (Graphics g = Graphics.FromImage(swatch))
using (SolidBrush b = new SolidBrush(colour)) {
g.FillRectangle(b, 0, 0, 64, 64);
}
item.Image = swatch;
item.DisplayStyle = ToolStripItemDisplayStyle.Image;
item.Margin = new Padding(2, 2, 2, 2);
drop_down.Items.Add(item);
}
}
private void ShowColorMenu(Point screen_location)
{
ContextMenuStrip context_menu = new ContextMenuStrip();
// The root context menu will not layout as a grid
FillDropDown(context_menu);
// This sub-menu will not layout as a grid
ToolStripMenuItem sub_menu = new ToolStripMenuItem("Sub-menu");
FillDropDown(sub_menu.DropDown);
context_menu.Items.Add(sub_menu);
// A sub-menu will layout as a grid if we create a new ToolStripDropDown for it
ToolStripMenuItem grid_sub_menu = new ToolStripMenuItem("Grid Sub-menu");
ToolStripDropDown new_drop_down = new ToolStripDropDown();
FillDropDown(new_drop_down);
grid_sub_menu.DropDown = new_drop_down;
context_menu.Items.Add(grid_sub_menu);
context_menu.Show(screen_location);
}
在我的机器上结果如下:
我想在上下文菜单的根目录中有一个图像网格。理解它为什么会这样也很好。我已经浏览了 .NET 引用源,但这一次没有帮助。
最佳答案
ContextMenuStrip由于菜单呈现/布局的限制,无法在表格布局中显示其 ToolStripMenuItems,并且您也无法将 ContextMenuStrip 强制转换为 ToolStripDropDown (或者反过来;它是 ToolStripDropDownMenu 周围的包装,它不能转换为其间接祖先:它将保留其特定功能(例如,您可以< em>将 TextBox 和 ListBox 都视为 Control
,但这并不意味着现在设置 ListBox 的 Text 实际上会在某处显示文本,只是因为 Text属性属于 Control 类)。
但是您可以像 ContextMenuStrip 一样直接使用和显示 ToolStripDropDown。 ToolStripDropDown 的 LayoutSettings可以直接转换到TableLayoutSettings和一个LayoutStyle类型 ToolStripLayoutStyle.Table完全支持。
在示例中,包含排列在表格布局中的 ToolStripMenuItems 的 ToolStripDropDown 对象用作 ContextMenuStrip,以选择要应用于 PictureBox 控件的彩色图像,而颜色名称显示在 Label 控件中。
下拉菜单在表单初始化时创建,在表单的 ClientArea 内单击鼠标右键时显示,并在表单关闭时释放:
注意1:在这里,我使用 Lambda 订阅 ToolStripDropDown.ItemClicked
事件。然而,对于这种类型的控件,最好使用方法委托(delegate)。
注意2:ToolStripDropDown 是通过调用contextColorMenu.Dispose();
来处理的。如果容器 Form 频繁打开和关闭,最好显式处置 ToolStripMenuItems Images。
using System.Drawing;
using System.Windows.Forms;
public partial class SomeForm : Form
{
private ToolStripDropDown contextColorMenu = null;
public SomeForm()
{
InitializeComponent();
contextColorMenu = new ToolStripDropDown();
contextColorMenu.ItemClicked += (o, a) => {
// Assign the selected Bitmap to a PitureBox.Image
picColor.Image = a.ClickedItem.Image;
// Show the Color description in a Label
lblColor.Text = ((Color)a.ClickedItem.Tag).ToString();
};
FillDropDown(contextColorMenu);
}
private void ShowColorMenu(Point location) => contextColorMenu.Show(location);
private void FillDropDown(ToolStripDropDown dropDown)
{
dropDown.LayoutStyle = ToolStripLayoutStyle.Table;
(dropDown.LayoutSettings as TableLayoutSettings).ColumnCount = 2;
(dropDown.LayoutSettings as TableLayoutSettings).GrowStyle = TableLayoutPanelGrowStyle.AddRows;
Color[] colors = { Color.Red, Color.Orange, Color.Yellow, Color.Green, Color.Blue, Color.Purple };
foreach (Color color in colors) {
var swatch = new Bitmap(64, 64);
using (var g = Graphics.FromImage(swatch)) {
g.Clear(color);
}
var item = new ToolStripMenuItem() {
DisplayStyle = ToolStripItemDisplayStyle.Image,
Image = swatch,
Tag = color,
Margin = new Padding(2),
Padding = new Padding(2, 1, 2, 1) // Fine tune the Items' Cell border
};
dropDown.Items.Add(item);
}
}
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
if (e.Button == MouseButtons.Right) {
ShowColorMenu(MousePosition);
}
}
protected override void OnFormClosed(FormClosedEventArgs e)
{
base.OnFormClosed(e);
contextColorMenu?.Dispose();
}
}
关于c# - ToolStripLayoutStyle.Table 在 ContextMenuStrip 中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62549612/