如何将图像放在ToolStripMenuItem(或类似控件)的文本旁边?

时间:2013-11-08 14:18:50

标签: c# .net winforms

我知道可以将图像添加到ToolStripMenuItem,就像下图中的“关闭所有文档”项一样:

Menu with some ToolStripMenuItems

但是,我想要达到的目标是:

enter image description here

即将图像放在项目文本的一侧,但不重叠检查空间。 我搜索了一下,但找不到可以做到这一点的Winforms控件。 你能指点我吗?或者我必须实施自己的? 谢谢。

编辑:谢谢大家的答案!我会在周末之后接受一个。

4 个答案:

答案 0 :(得分:3)

你必须使用一些自定义绘画。有一些方法可以实现这一点,但我想介绍使用一些自定义ToolStripRenderer。以下只是一个演示代码,您可以自己改进它。为方便起见,我将每个内部图片保存在相应的项目Tag中:

public class CustomRenderer : ToolStripProfessionalRenderer
{
    int innerImagePadding = 2;
    protected override void OnRenderItemText(ToolStripItemTextRenderEventArgs e) {
        Image img = e.Item.Tag as Image;
        if(img == null) base.OnRenderItemText(e);
        else {
          e.Graphics.DrawImage(img, e.Item.ContentRectangle.Left + e.Item.Bounds.Height + innerImagePadding,
                               e.Item.ContentRectangle.Top + innerImagePadding, 
                               Math.Max(1, e.Item.ContentRectangle.Height - innerImagePadding*2), 
                               Math.Max(1, e.Item.ContentRectangle.Height - innerImagePadding*2));              
          Rectangle textRect = new Rectangle(e.Item.ContentRectangle.Left + e.Item.Bounds.Height*2, 
                               e.Item.ContentRectangle.Top +1, 
                               e.TextRectangle.Width, 
                               e.TextRectangle.Height);
          e.Graphics.DrawString(e.Text, e.TextFont, new SolidBrush(e.TextColor), textRect);
       }
    }
}

//Usage
ContextMenuStrip cm = new ContextMenuStrip();
cm.Items.Add(new ToolStripMenuItem("Clear all", myImage) {Tag = myImage});
cm.Items.Add(new ToolStripMenuItem("Remove all", myImage){Tag = myImage});
this.ContextMenuStrip = cm; //set the ContextMenuStrip for the form
//set the custom Renderer
cm.Renderer = new CustomRenderer();

enter image description here

答案 1 :(得分:2)

您无法从设计器中执行此操作,但您可以通过将父DropDown属性强制转换为ToolStripDownDownMenu项来显示额外的边距,以访问Show属性:

public Form1() {
  InitializeComponent();
  ((ToolStripDropDownMenu)FileMenuItem.DropDown).ShowCheckMargin = true;
  ((ToolStripDropDownMenu)FileMenuItem.DropDown).ShowImageMargin = true;
}

结果:

enter image description here

答案 2 :(得分:1)

您可以使用paint事件在控件的任何位置绘制任何内容。例如 -

void myToolStripMenuItem1_Paint(object sender, PaintEventArgs e)
{
    e.Graphics.DrawImage(Image.FromFile("open_icon.jpg"), 0, 0);
}

这会将图像置于(0,0)位置。你可以把它放在任何你想要的地方。

答案 3 :(得分:0)

标准.NET API中没有具有此功能的控件,因此您必须自己编写它作为新功能。

但是,根据您希望使用此“新”功能的频率,可能会有有效的方法来实现它。我认为可以巧妙地工作的一个解决方案是利用这些图像具有固定大小的事实,并相应地缩进文本。

考虑如下方法:

using System.Drawing;

const string MENU_TEXT_INDENT = "           ";

private void MenuItemWithImage_Paint(Object sender, PaintEventArgs e) {
    ToolStripMenuItem menuItem = sender as ToolStripMenuItem;
    if (!menuItem.Text.StartsWith(MENU_TEXT_INDENT)) {
        menuItem.Text = menuItem.Text.Insert(0, MENU_TEXT_INDENT);
    }
    Image img = menuItem.Image;
    e.Graphics.DrawImage(img, new Point(0, 0));
    menuItem.Refresh(); // May be needed to reflect changes - try without though!
}

如果然后将此事件处理程序附加到每个菜单项的Paint事件,并且图像以这种方式呈现,则这应该有效。 (您可能需要更多或更少的空间 - 我自己没有测试过它)