Показать изображение для 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);
}
});
}
}