C# ToolStripProfessionalRender,事件 OnRenderItemText 仅应用于第一个项目

C# ToolStripProfessionalRender, event OnRenderItemText applied only on the first item

我正在使用 ToolStripProfessionalRender 绘制自定义工具条,并按如下方式编辑 OnRenderItemText 事件:

protected override void OnRenderItemText(ToolStripItemTextRenderEventArgs e)
{
    e.Item.ForeColor = Clr.White;
    e.Item.TextAlign = ContentAlignment.MiddleLeft;
    e.Item.Alignment = ToolStripItemAlignment.Left;
    base.OnRenderItemText(e);
    if (e.Item.GetType() == typeof(ToolStripDropDownButton))
    {
        ToolStripDropDownButton tsmi = (ToolStripDropDownButton)e.Item;
        if (tsmi.HasDropDownItems && tsmi.OwnerItem == null)
        {
            Rectangle bounds = tsmi.Bounds;
            bounds.X = bounds.Right - 25;
            bounds.Width = 25;
            bounds.Y = 10;

            // Draw the corner
            Graphics G = e.Graphics;
            SolidBrush brushw = new SolidBrush(Color.FromArgb(70,70,70));
            Point[] points =
            {
                new Point(bounds.Right - 3, bounds.Height - 11), // point top right
                new Point(bounds.Right - 3, bounds.Bottom - 14), // point bottom right
                new Point(bounds.Right - 10, bounds.Bottom - 14) // point bottom left

            };
            G.FillPolygon(brushw, points);
        }
    }
}

基本上我试图获得的输出如下:

所以当我得到一个 ToolStripDropDownButton 时,在右下角画了一个小三角形。问题是小三角形只画了第一项。

为了结束这个问题,我使用一个在每次调用时添加下拉按钮的函数动态绘制了这个工具条。

ToolStripDropDownButton m_Item = new ToolStripDropDownButton(text, image);
                        m_Item.ImageAlign = ContentAlignment.MiddleCenter;
                        m_Item.ImageScaling = ToolStripItemImageScaling.None;
                        m_Item.Name = name;
                        m_Item.ForeColor = Color.White;
                        m_Item.BackColor = Color.FromArgb(95, 95, 95);
                        m_Item.Padding = new Padding(5);
                        m_Item.ShowDropDownArrow = false;
                        m_Item.Paint += new PaintEventHandler(this.PaintButtonBorder);
                        if (tabPage != null)
                            m_Item.Click += (sender, e) => AddClickTab(sender, e, tabPage);
                        ((ToolStripDropDownMenu)m_Item.DropDown).ShowImageMargin = false;
                        ((ToolStripDropDownMenu)m_Item.DropDown).ShowCheckMargin = false;
                        ((ToolStripDropDownMenu)m_Item.DropDown).Cursor = Cursors.Hand;
                        toolStrip1.Items.Add(m_Item);

                        if (SubItems != null)
                        {
                            for(int i = 0; i < SubItems.Length; i++)
                            {
                                object[] subitem = (object[])SubItems[i];
                                FnAddToolStripMenuItem(
                                    subitem[0].ToString(),
                                    subitem[1].ToString(),
                                    (Bitmap)subitem[2],
                                    m_Item,
                                    (TabPage)subitem[3]
                                    );
                            }
                        }

我是不是漏掉了一些“新”东西?

重写 OnRenderItemText 方法只绘制文本部分,and/or 设置渲染文本时使用的默认属性。要更改下拉项箭头的外观和形状,请覆盖 OnRenderArrow 方法。

例子

using System.Drawing;
using System.Drawing.Drawing2D;

protected override void OnRenderArrow(ToolStripArrowRenderEventArgs e)
{
    // Optional: to be the default color of the arrows.
    e.ArrowColor = Color.FromArgb(70, 70, 70);

    if (e.Item is ToolStripDropDownButton item && item.OwnerItem == null)
    {
        var g = e.Graphics;
        var r = new Rectangle(item.Bounds.Width - 10, item.Bounds.Height - 10, 8, 8);

        g.SmoothingMode = SmoothingMode.AntiAlias;
        g.PixelOffsetMode = PixelOffsetMode.Half;

        using (var br = new SolidBrush(e.ArrowColor))
            g.FillPolygon(br, new[]
            {
                new Point(r.Left, r.Bottom),
                new Point(r.Right, r.Top),
                new Point(r.Right, r.Bottom)
            });

        g.SmoothingMode = SmoothingMode.None;
        g.PixelOffsetMode = PixelOffsetMode.Default;
    }
    else
        base.OnRenderArrow(e);
}

protected override void OnRenderItemText(ToolStripItemTextRenderEventArgs e)
{
    e.Item.ForeColor = Color.White;
    e.Item.TextAlign = ContentAlignment.MiddleLeft;
    e.Item.Alignment = ToolStripItemAlignment.Left;
    base.OnRenderItemText(e);
}

确保启用下拉按钮的 ShowDropDownArrow 属性。所以评论这个 m_Item.ShowDropDownArrow = false;.

如果您也有兴趣根据下拉按钮的当前状态(选中、按下)更改颜色,那么您可以这样做:

using (var br = new SolidBrush(item.Selected 
    ? Color.FromArgb(150, 150, 150) : item.Pressed 
    ? Color.FromArgb(100, 100, 100) :
      Color.FromArgb(70, 70, 70)))
    //...