2

我有一个 ToolStripSplitButton,下拉列表中有各种元素。其中之一是包含在 ToolStripControlHost 中的 Trackbar,称为 ToolStripTrackbarItem。这是代码(我从stackoverflow得到它):

using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using System.Windows.Forms.Design;

namespace Application
{
    [System.ComponentModel.DesignerCategory("code")]
    [System.Windows.Forms.Design.ToolStripItemDesignerAvailability(ToolStripItemDesignerAvailability.ContextMenuStrip | ToolStripItemDesignerAvailability.MenuStrip)]

    public class ToolStripTrackbarItem : ToolStripControlHost
    {
        public ToolStripTrackbarItem()
            : base(CreateControlInstance())
        {
            this.Size = Control.Size;
        }
        public TrackBar TrackBar
        {
            get { return Control as TrackBar; }
        }
        private static Control CreateControlInstance()
        {
            TrackBar t = new TrackBar();
            t.AutoSize = false;
            return t;
        }
        [DefaultValue(0)]
        public int Value
        {
            get { return TrackBar.Value; }
            set { TrackBar.Value = value; }
        }
        protected override void OnSubscribeControlEvents(Control control)
        {
            base.OnSubscribeControlEvents(control);
            TrackBar trackBar = control as TrackBar;
            trackBar.ValueChanged += new EventHandler(trackBar_ValueChanged);
        }
        protected override void OnUnsubscribeControlEvents(Control control)
        {
            base.OnUnsubscribeControlEvents(control);
            TrackBar trackBar = control as TrackBar;
            trackBar.ValueChanged -= new EventHandler(trackBar_ValueChanged);
        }
        void trackBar_ValueChanged(object sender, EventArgs e)
        {
            if (this.ValueChanged != null)
                ValueChanged(sender, e);
        }
        public event EventHandler ValueChanged;
        protected override Size DefaultSize
        {
            get { return new Size(300, 16); }
        }
    }

它有效,但我需要在下拉项目的左侧显示图像:

菜单

通过设置 Image 属性,我成功使用了简单的 ToolStripMenuItem。但是,设置我的 ToolStripTrackbarItem 的 Image 属性(从 ToolStripControlHost 继承,参见上面的代码)是无效的。根据 MSDN,Image 属性与 ToolStripControlHost 无关。

这是什么意思?甚至不可能包含留给 ToolStripControlHost 的图像吗?

如果有可能的话,该怎么做?

4

1 回答 1

4

你应该在这里解决2个问题:

  • ToolStripControlHost保存表单时不显示Image属性,也不序列化图像。
  • ToolStripProfessionalRendered不为ToolStripControlHost.

您需要覆盖Image的属性ToolStripControlHost并使其可浏览和可序列化。您还需要创建一个自定义渲染器以正确的位置和大小绘制图像。然后,如果您只是将渲染器设置为ToolStrip使用以下代码,您将获得预期的结果:

this.toolStrip1.Renderer = new MyCustomRenderer();

在此处输入图像描述

ToolStripTrackBar

该项目使Image属性显示在属性网格中,并在保存表单时让它序列化。

using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using System.Windows.Forms.Design;
[ToolStripItemDesignerAvailability(ToolStripItemDesignerAvailability.All)]
public class ToolStripTrackBar : ToolStripControlHost
{
    public TrackBar TrackBar { get { return (TrackBar)Control; } }
    public ToolStripTrackBar() : base(CreateControl()) { }
    private static TrackBar CreateControl()
    {
        var t = new TrackBar()
        { TickStyle = TickStyle.None, AutoSize = false, Height = 28 };
        return t;
    }
    [Browsable(true)]
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
    public override Image Image
    {
        get { return base.Image; }
        set { base.Image = value; }
    }
    /*Expose properties and events which you need.*/
    public int Value
    {
        get { return TrackBar.Value; }
        set { TrackBar.Value = value; }
    }
}

我的自定义渲染器

此渲染器为ToolStripTrackBar.

using System.Drawing;
using System.Linq;
using System.Windows.Forms;
public class MyCustomRenderer : ToolStripProfessionalRenderer
{
    protected override void OnRenderImageMargin(ToolStripRenderEventArgs e)
    {
        base.OnRenderImageMargin(e);
        e.ToolStrip.Items.OfType<ToolStripTrackBar>()
         .ToList().ForEach(item =>
         {
             if (item.Image != null)
             {
                 var size = item.GetCurrentParent().ImageScalingSize;
                 var location = item.Bounds.Location;
                 location = new Point(5, location.Y + 1);
                 var imageRectangle = new Rectangle(location, size);
                 e.Graphics.DrawImage(item.Image, imageRectangle,
                     new Rectangle(Point.Empty, item.Image.Size),
                     GraphicsUnit.Pixel);
             }
         });
    }
}
于 2017-04-02T02:51:02.703 回答