2017-08-11 60 views
1

我已經創建了一個自定義用戶控件,它將顯示文本和指示燈以顯示我們服務的當前運行狀態,如下面的表格所示。它在窗體上工作得很好,但我想把它放在一個StatusStrip控件上。我創建了一個派生自ToolStripControlHost的類,以支持我在StatusStrip上的控件,但它根本不渲染。控件的寬度爲零,表單在IDE中打開時閃爍。如何在ToolStrip上渲染圖形

我已經看過ToolStripRendering類,但在我看來,它打算用於現有的受支持的控件。

達到此目的的最佳方法是什麼?如果甚至可能?我的代碼如下。

我使用Visual Studio 2010和.NET 4.0

enter image description here

用戶控制代碼:

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()) 
    { 
    } 
} 
+0

要託管你的UC不應該通過構造函數傳遞給主機? 'public ToolStripServiceStatus(ServiceStatus sStatus)' – TaW

+0

@Taw,它被傳遞給基類的構造函數 – tdemay

回答

0

我超過這個。 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; 
    } 
}