Показать изображение для ToolStripControlHost в выпадающем меню

У меня есть ToolStripSplitButton с различными элементами в раскрывающемся списке. Одним из них является трекбар, заключенный в ToolStripControlHost, который называется ToolStripTrackbarItem. Это код (я получил его из stackru):

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); }
        }
    }

Это работает, но мне нужно показать изображения слева от выпадающих элементов:

меню

Я добился успеха с простым ToolStripMenuItem, установив свойство Image. Однако неэффективно устанавливать свойство Image моего ToolStripTrackbarItem (которое наследуется от ToolStripControlHost, см. Код выше). Согласно MSDN, свойство Image не имеет отношения к ToolStripControlHost.

Что это значит? Разве невозможно включить изображение, оставленное в ToolStripControlHost?

Если это все равно возможно, как это сделать?

1 ответ

Решение

Вы должны решить 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; }
    }
}

MyCustomRenderer

Этот рендерер рисует изображения для 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);
             }
         });
    }
}
Другие вопросы по тегам