C# 如何在ToolStrip上渲染图形

C# 如何在ToolStrip上渲染图形,c#,toolstrip,toolstripcontrolhost,C#,Toolstrip,Toolstripcontrolhost,我已经创建了一个自定义用户控件,它将显示文本和一个指示灯,以显示我们服务的当前运行状态,如下表所示。它在窗体上工作得很好,但我想将它放在StatusStrip控件上。我创建了一个派生自ToolStripControlHost的类,以支持StatusStrip上的控件,但它根本不呈现。控件的宽度为零,窗体在IDE中打开时闪烁 我已经看过ToolStripRendering类,但在我看来,它是用于现有支持的控件的 实现这一目标的最佳方式是什么?如果可能的话?我的代码如下 我正在使用Visual St

我已经创建了一个自定义用户控件,它将显示文本和一个指示灯,以显示我们服务的当前运行状态,如下表所示。它在窗体上工作得很好,但我想将它放在StatusStrip控件上。我创建了一个派生自ToolStripControlHost的类,以支持StatusStrip上的控件,但它根本不呈现。控件的宽度为零,窗体在IDE中打开时闪烁

我已经看过ToolStripRendering类,但在我看来,它是用于现有支持的控件的

实现这一目标的最佳方式是什么?如果可能的话?我的代码如下

我正在使用Visual Studio 2010和.NET 4.0

用户控制代码:

public partial class ServiceStatus : UserControl
{
    public ServiceStatus()
    {
        IndicatorSize = new System.Drawing.Size(20, 20);
        Padding = new Padding(1, 1, 1, 1);
        InitializeComponent();
    }

    public ServiceControllerStatus GetStatus()
    {
        using (var service = new ServiceController("MyService"))
        {
            return service.Status;
        }
    }
    private void getStatusInfo(out string statusText, out Color indicatorColor)
    {
        try
        {
            ServiceControllerStatus status = GetStatus();
            switch (status)
            {
                case ServiceControllerStatus.ContinuePending:
                    statusText = Properties.Resources.SERVICE_CONTINUE_PENDING;
                    indicatorColor = Color.Yellow;
                    break;
                case ServiceControllerStatus.Paused:
                    statusText = Properties.Resources.SERVICE_PAUSED;
                    indicatorColor = Color.Yellow;
                    break;
                case ServiceControllerStatus.PausePending:
                    statusText = Properties.Resources.SERVICE_PAUSE_PENDING;
                    indicatorColor = Color.Yellow;
                    break;
                case ServiceControllerStatus.Running:
                    statusText = Properties.Resources.SERVICE_RUNNING;
                    indicatorColor = Color.Green;
                    break;
                case ServiceControllerStatus.StartPending:
                    statusText = Properties.Resources.SERVICE_START_PENDING;
                    indicatorColor = Color.Yellow;
                    break;
                case ServiceControllerStatus.Stopped:
                    statusText = Properties.Resources.SERVICE_STOPPED;
                    indicatorColor = Color.Red;
                    break;
                case ServiceControllerStatus.StopPending:
                    statusText = Properties.Resources.SERVICE_STOP_PENDING;
                    indicatorColor = Color.Yellow;
                    break;
                default:
                    statusText = default(String);
                    indicatorColor = default(Color);
                    break;
            }
        }
        catch
        {
            statusText = Properties.Resources.SERVICE_CANNOT_CONNECT;
            indicatorColor = Color.Red;
        }
    }

    public Size IndicatorSize { get; set; }


    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);
        string statusText;
        Color indicatorColor;

        getStatusInfo(out statusText, out indicatorColor);

        Size textSize = TextRenderer.MeasureText(e.Graphics, statusText, Font, new Size(int.MaxValue, int.MinValue), TextFormatFlags.NoPadding);
        this.Size = new Size(Padding.Left + textSize.Width + 5 + IndicatorSize.Width + Padding.Right,
                               Padding.Top + Math.Max(textSize.Height, IndicatorSize.Height) + Padding.Bottom);
        Point textStart = new Point(Padding.Left, (this.Size.Height-textSize.Height) / 2);
        Rectangle textBounds = new Rectangle(textStart, textSize) ;
        Brush indicatorBrush = new SolidBrush(indicatorColor) ;
        Point indicatorStart = new Point(textStart.X + textSize.Width + 5, (this.Size.Height-IndicatorSize.Height) / 2) ;
        Rectangle indicatorBounds = new Rectangle(indicatorStart, IndicatorSize) ;

        e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
        TextRenderer.DrawText(e.Graphics, statusText, Font, textBounds, ForeColor, TextFormatFlags.NoPadding);
        e.Graphics.FillEllipse(indicatorBrush, indicatorBounds);
    }
}
工具条控制主机代码:

[ToolStripItemDesignerAvailability(ToolStripItemDesignerAvailability.All)]
public class ToolStripServiceStatus : ToolStripControlHost
{
    public ToolStripServiceStatus()
        : base(new ServiceStatus())
    {
    }
}

我想得太多了。ToolStripStatusLabel具有文本和图像属性

[ToolStripItemDesignerAvailability(ToolStripItemDesignerAvailability.All)]
public class ToolStripServiceStatus : ToolStripStatusLabel
{
    Timer _statusRefresh = null;
    public ToolStripServiceStatus() : base()
    {
        this.TextImageRelation = System.Windows.Forms.TextImageRelation.TextBeforeImage;
        RefreshStatus();
    }

    void _statusRefresh_Tick(object sender, EventArgs e)
    {
        RefreshStatus();
    }

    public ServiceControllerStatus GetStatus()
    {
        using (var service = new ServiceController("MyService"))
        {
            return service.Status;
        }
    }
    public ServiceControllerStatus GetStatusInfo(out string statusText, out Color indicatorColor)
    {
        ServiceControllerStatus status = default(ServiceControllerStatus);
        try
        {
            status = GetStatus();
            switch (status)
            {
                case ServiceControllerStatus.ContinuePending:
                    statusText = Properties.Resources.SERVICE_CONTINUE_PENDING;
                    indicatorColor = Color.Yellow;
                    break;
                case ServiceControllerStatus.Paused:
                    statusText = Properties.Resources.SERVICE_PAUSED;
                    indicatorColor = Color.Yellow;
                    break;
                case ServiceControllerStatus.PausePending:
                    statusText = Properties.Resources.SERVICE_PAUSE_PENDING;
                    indicatorColor = Color.Yellow;
                    break;
                case ServiceControllerStatus.Running:
                    statusText = Properties.Resources.SERVICE_RUNNING;
                    indicatorColor = Color.Green;
                    break;
                case ServiceControllerStatus.StartPending:
                    statusText = Properties.Resources.SERVICE_START_PENDING;
                    indicatorColor = Color.Yellow;
                    break;
                case ServiceControllerStatus.Stopped:
                    statusText = Properties.Resources.SERVICE_STOPPED;
                    indicatorColor = Color.Red;
                    break;
                case ServiceControllerStatus.StopPending:
                    statusText = Properties.Resources.SERVICE_STOP_PENDING;
                    indicatorColor = Color.Yellow;
                    break;
                default:
                    statusText = default(String);
                    indicatorColor = default(Color);
                    break;
            }
        }
        catch
        {
            statusText = Properties.Resources.SERVICE_CANNOT_CONNECT;
            indicatorColor = Color.Red;
        }
        return status;
    }

    string _previousStatusText = "";
    public ServiceControllerStatus RefreshStatus()
    {
        if (_statusRefresh == null)
        {
            _statusRefresh = new Timer() { Interval = 1000 };
            _statusRefresh.Tick += new EventHandler(_statusRefresh_Tick);
        }
        _statusRefresh.Enabled = false;
        string statusText;
        Color indicatorColor;
        ServiceControllerStatus status = GetStatusInfo(out statusText, out indicatorColor);

        if (_previousStatusText != statusText)
        {
            Text = statusText;
            Image bmp = new Bitmap(Height, Height);
            using (Graphics g = Graphics.FromImage(bmp))
            {
                g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
                g.FillEllipse(new SolidBrush(indicatorColor), new Rectangle(0, 0, Height - 1, Height - 1));
            }
            this.Image = bmp;
        }
        _statusRefresh.Enabled = (status != ServiceControllerStatus.Stopped && status != ServiceControllerStatus.Running && status != ServiceControllerStatus.Paused);
        return status;
    }
}

我想得太多了。ToolStripStatusLabel具有文本和图像属性

[ToolStripItemDesignerAvailability(ToolStripItemDesignerAvailability.All)]
public class ToolStripServiceStatus : ToolStripStatusLabel
{
    Timer _statusRefresh = null;
    public ToolStripServiceStatus() : base()
    {
        this.TextImageRelation = System.Windows.Forms.TextImageRelation.TextBeforeImage;
        RefreshStatus();
    }

    void _statusRefresh_Tick(object sender, EventArgs e)
    {
        RefreshStatus();
    }

    public ServiceControllerStatus GetStatus()
    {
        using (var service = new ServiceController("MyService"))
        {
            return service.Status;
        }
    }
    public ServiceControllerStatus GetStatusInfo(out string statusText, out Color indicatorColor)
    {
        ServiceControllerStatus status = default(ServiceControllerStatus);
        try
        {
            status = GetStatus();
            switch (status)
            {
                case ServiceControllerStatus.ContinuePending:
                    statusText = Properties.Resources.SERVICE_CONTINUE_PENDING;
                    indicatorColor = Color.Yellow;
                    break;
                case ServiceControllerStatus.Paused:
                    statusText = Properties.Resources.SERVICE_PAUSED;
                    indicatorColor = Color.Yellow;
                    break;
                case ServiceControllerStatus.PausePending:
                    statusText = Properties.Resources.SERVICE_PAUSE_PENDING;
                    indicatorColor = Color.Yellow;
                    break;
                case ServiceControllerStatus.Running:
                    statusText = Properties.Resources.SERVICE_RUNNING;
                    indicatorColor = Color.Green;
                    break;
                case ServiceControllerStatus.StartPending:
                    statusText = Properties.Resources.SERVICE_START_PENDING;
                    indicatorColor = Color.Yellow;
                    break;
                case ServiceControllerStatus.Stopped:
                    statusText = Properties.Resources.SERVICE_STOPPED;
                    indicatorColor = Color.Red;
                    break;
                case ServiceControllerStatus.StopPending:
                    statusText = Properties.Resources.SERVICE_STOP_PENDING;
                    indicatorColor = Color.Yellow;
                    break;
                default:
                    statusText = default(String);
                    indicatorColor = default(Color);
                    break;
            }
        }
        catch
        {
            statusText = Properties.Resources.SERVICE_CANNOT_CONNECT;
            indicatorColor = Color.Red;
        }
        return status;
    }

    string _previousStatusText = "";
    public ServiceControllerStatus RefreshStatus()
    {
        if (_statusRefresh == null)
        {
            _statusRefresh = new Timer() { Interval = 1000 };
            _statusRefresh.Tick += new EventHandler(_statusRefresh_Tick);
        }
        _statusRefresh.Enabled = false;
        string statusText;
        Color indicatorColor;
        ServiceControllerStatus status = GetStatusInfo(out statusText, out indicatorColor);

        if (_previousStatusText != statusText)
        {
            Text = statusText;
            Image bmp = new Bitmap(Height, Height);
            using (Graphics g = Graphics.FromImage(bmp))
            {
                g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
                g.FillEllipse(new SolidBrush(indicatorColor), new Rectangle(0, 0, Height - 1, Height - 1));
            }
            this.Image = bmp;
        }
        _statusRefresh.Enabled = (status != ServiceControllerStatus.Stopped && status != ServiceControllerStatus.Running && status != ServiceControllerStatus.Paused);
        return status;
    }
}

要托管UC,您不应该通过构造函数将其传递到主机吗
public ToolStripServiceStatus(ServiceStatus sStatus)
@Taw,它被传递给基类构造函数来承载您的UC您不应该通过构造函数将其传递给主机吗<代码>公共工具StripServiceStatus(ServiceStatus sStatus)@Taw,它被传递给基类构造函数