【问题标题】:Show Image for ToolStripControlHost in drop down menu在下拉菜单中显示 ToolStripControlHost 的图像
【发布时间】:2017-04-01 13:22:32
【问题描述】:

我有一个 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 的图像吗?

如果有可能,该怎么做?

【问题讨论】:

    标签: c# .net winforms toolstrip toolstripcontrolhost


    【解决方案1】:

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

    • ToolStripControlHost 不显示 Image 属性,也不会在您保存表单时序列化图像。
    • ToolStripProfessionalRendered 不会为 ToolStripControlHost 绘制图像。

    您需要覆盖ToolStripControlHostImage 属性并使其可浏览和可序列化。您还需要创建一个自定义渲染器以正确的位置和大小绘制图像。然后,如果您简单地使用以下代码为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);
                 }
             });
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-06-24
      • 1970-01-01
      • 1970-01-01
      • 2012-05-27
      • 1970-01-01
      • 2020-09-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多