2012-03-10 44 views
0

即時通訊有一些問題與一些文本即時消息寫在進度條上,它會顯示但一旦GUI線程完成繪圖後會消失,並且運行循環的單獨線程再次開始。我假設這是因爲它超出了範圍,但我不知道如何解決它。進度條上的文本超出範圍

總體佈局如下:其處理在單獨的線程一串數據,並提出了每個循環之後的事件

namespace namespace1 
{ 
    public partial class Form1:Form 
    { 
    .... 
    } 

    public class ProgressBar 
    { 
     public void SubscribeToUpdateEvent() 
     { 
      //subscribe incrementPB to event 
     } 

     public void IncrementPB(object sender, EventArgs e) 
     { 
      //Update progress bar's value 
      DrawPercentage(value);   
     } 

     public void DrawPercentage(Value) 
     { 

     using (Graphics Draw = statusBar.CreateGraphics()) 
     { 
      Draw.DrawString(percentage.ToString() + "%", ProgressBar.DefaultFont, Brushes.Black, new PointF((statusBar.Width/2) - ((Draw.MeasureString(percentage.ToString() + "%", ProgressBar.DefaultFont)).Width/2.0F), 
       (statusBar.Height/2) - ((Draw.MeasureString(percentage.ToString() + "%", ProgressBar.DefaultFont)).Height/2.0F))); 
     } 
    } 
} 

//第二文件。

namespace namespace2 
{ 
    public class MyClass 
    { 
     public void iterator() 
     { 
      for(int i=0;i<10;i++) 
      { 
       //raise event to update the progress bar here 
      } 
     } 
    } 
} 

感謝您的幫助。

回答

1

當進度條上發生下一個Paint事件時,百分比標籤可能會被擦除。嘗試將進度條實現爲用戶控件,這樣您可以覆蓋OnPaint方法並在那裏呈現文本(在base.OnPaint(e)之後)。
我做了幾個簡單的類來模擬你的情況。下面是對我的作品的辦法:

1)的進度條控件(簡單的實現,只是勾勒與OnPaint中的基本概念):

public partial class CustomProgressBar : UserControl 
{ 
    public int Percentage { get; set; } 

    public CustomProgressBar() 
    { 
     InitializeComponent(); 
    } 

    protected override void OnPaint(PaintEventArgs e) 
    { 
     base.OnPaint(e); 
     Graphics g = e.Graphics; 
     Rectangle bounds = new Rectangle(ClientRectangle.X, ClientRectangle.Y, ClientRectangle.Width - 1, ClientRectangle.Height - 1); 

     // Paint a green bar indicating the progress. 
     g.FillRectangle 
     (
      Brushes.LimeGreen, 
      new Rectangle 
      (
       bounds.X, 
       bounds.Y, 
       (int)(bounds.Width * Percentage/100.0), 
       bounds.Height 
      ) 
     ); 

     // Draw a black frame around the progress bar. 
     g.DrawRectangle(Pens.Black, bounds); 

     // Draw the percentage label. 
     TextRenderer.DrawText(g, Percentage + "%", Font, bounds, ForeColor); 
    } 
} 

2)班表示作業運行後臺線程:

public class BackgroundJob 
{ 
    public event Action<object, int> StepCompleted; 

    public void Execute() 
    { 
     const int TotalSteps = 10; 
     for (int step = 1; step <= TotalSteps; step++) 
     { 
      // Execute some heavy work here. 
      Thread.Sleep(1000); 

      // Calculate percentage (0..100). 
      int percentage = (int)(step * 100.0/TotalSteps); 

      // Notify the subscribers that the step has been completed. 
      OnStepCompleted(percentage); 
     } 
    } 

    protected virtual void OnStepCompleted(int percentage) 
    { 
     if (StepCompleted != null) 
     { 
      StepCompleted(this, percentage); 
     } 
    } 
} 

3)Form類。包含自定義進度條控件,並在按下按鈕時啓動後臺作業。

public partial class MainForm : Form 
{ 
    public MainForm() 
    { 
     InitializeComponent(); 
    } 

    private void btnStartJob_Click(object sender, EventArgs e) 
    { 
     Thread backgroundThread = new Thread 
     (
      () => 
      { 
       var job = new BackgroundJob(); 
       job.StepCompleted += job_StepCompleted; 
       job.Execute(); 
      } 
     ); 
     backgroundThread.Start(); 
    } 

    private void job_StepCompleted(object sender, int percentage) 
    { 
     progressBar.Percentage = percentage; 

     // Force the progress bar to redraw itself. 
     progressBar.Invalidate(); 
    } 
} 

你可以叫Invalidate()內部(在Percentage屬性setter裏面),我單獨調用它只是強調繪畫過程是如何觸發。

+0

我給它一個鏡頭,看看它是怎麼回事。非常感謝您花時間回答我的問題,非常感謝! – 2012-03-10 13:01:40

+0

我看到了UserControl類,我找不到OnPaint事件。你知道爲什麼它沒有在MSDN上列出嗎?或者我看錯了地方?謝謝。 – 2012-03-11 13:57:35

+0

@HansRudel:這是一個受保護的虛擬方法。事件的名稱是'Paint',這個方法只負責提升它。在這種情況下,我們調用'base.OnPaint(e)',觸發'Paint'事件,然後繪製我們自定義的圖形。 – 2012-03-11 14:48:36