2016-05-13 50 views
1

我在微調控件中工作。我希望控件支持透明背色。當繪製圓弧時,中間有一個空白區域,我希望這個空間是真正透明的,這樣我就可以把另一個控件放在它後面,而且它不會被微調器覆蓋。在其他控件上方顯示透明加載微調器

我試着重寫CreateParams void。
另外我設置樣式以支持TransparentColor。
嘗試覆蓋OnPaintBackground void,但我無法實現真正​​的透明背色。

那麼,你能建議我做什麼?

+0

你可以看到在這個崗位透明微調。 [爲什麼當兩個自定義控件添加了計時器時,設計器變慢?](http://stackoverflow.com/questions/36195226/why-does-the-designer-slowing-when-two-custom-controls-has-timer-添加?)這裏描述了相同的技術,使一個透明的圖片框和標籤。 [如何用c#製作兩個透明圖層?](http:// stackoverflow。com/questions/36099017/how-to-make-two-transparent-layer-with-c) –

+0

@Reza Aghaei看到這兩個帖子,但我無法獲得真正的透明度。我還複製了您鏈接的第一篇文章中的SpinningCircles控件。但是那個沒有實現真正的透明背景。 – ChrisCreateBoss

+0

至少對於我分享的第二個鏈接,您可以看到包含透明圖片框和透明標籤的屏幕截圖。那究竟是什麼問題? –

回答

4

要製作透明圖層,應該重寫控件的繪製並按此順序繪製控件,第一個將位於您的控制下的所有控件(基於z-index)繪製在位圖上。 然後在您的控件的圖形上繪製位圖。 最後繪製控件的內容。 另外您控制的BackColor應該是Color.Transparent

此外,作爲製作透明圖層的另一選項,您可以在繪製時從控件中排除某些區域。

在下面的示例中,我使用了第一種技術並創建了2個控件。 A透明控制spinning circles。和一個transparent picturebox控制。

在這兩個示例中,我使用加載行之間的延遲來顯示微調器是否有意義。

樣品1 - 使用SpinningCircles控制

SpinningCircles控制繪製圓圈和支持透明度。控件在設計時沒有動畫,但在運行時動畫。當它不可見時,它也不消耗資源。

enter image description here

樣品2 - 使用TransparentPictureBox控制和透明動畫GIF TransparentPictureBox控制支持透明度,所以就用GIF動畫作爲其圖像和作爲你可以看到,GIF被正確顯示。

enter image description here

示例代碼1 - SpinningCircles

using System; 
using System.Drawing; 
using System.Drawing.Drawing2D; 
using System.Linq; 
using System.Windows.Forms; 
public class SpinningCircles : Control 
{ 
    int increment = 1; 
    int radius = 4; 
    int n = 8; 
    int next = 0; 
    Timer timer; 
    public SpinningCircles() 
    { 
     timer = new Timer(); 
     this.Size = new Size(100, 100); 
     timer.Tick += (s, e) => this.Invalidate(); 
     if (!DesignMode) 
      timer.Enabled = true; 
     SetStyle(ControlStyles.AllPaintingInWmPaint | 
       ControlStyles.OptimizedDoubleBuffer | 
       ControlStyles.ResizeRedraw | ControlStyles.UserPaint | 
       ControlStyles.SupportsTransparentBackColor, true); 
     BackColor = Color.Transparent; 
    } 
    protected override void OnPaint(PaintEventArgs e) 
    { 
     if (Parent != null && this.BackColor == Color.Transparent) 
     { 
      using (var bmp = new Bitmap(Parent.Width, Parent.Height)) 
      { 
       Parent.Controls.Cast<Control>() 
         .Where(c => Parent.Controls.GetChildIndex(c) > Parent.Controls.GetChildIndex(this)) 
         .Where(c => c.Bounds.IntersectsWith(this.Bounds)) 
         .OrderByDescending(c => Parent.Controls.GetChildIndex(c)) 
         .ToList() 
         .ForEach(c => c.DrawToBitmap(bmp, c.Bounds)); 

       e.Graphics.DrawImage(bmp, -Left, -Top); 
      } 
     } 
     e.Graphics.SmoothingMode = SmoothingMode.HighQuality; 
     int length = Math.Min(Width, Height); 
     PointF center = new PointF(length/2, length/2); 
     int bigRadius = length/2 - radius - (n - 1) * increment; 
     float unitAngle = 360/n; 
     if (!DesignMode) 
      next++; 
     next = next >= n ? 0 : next; 
     int a = 0; 
     for (int i = next; i < next + n; i++) 
     { 
      int factor = i % n; 
      float c1X = center.X + (float)(bigRadius * Math.Cos(unitAngle * factor * Math.PI/180)); 
      float c1Y = center.Y + (float)(bigRadius * Math.Sin(unitAngle * factor * Math.PI/180)); 
      int currRad = radius + a * increment; 
      PointF c1 = new PointF(c1X - currRad, c1Y - currRad); 
      e.Graphics.FillEllipse(Brushes.Black, c1.X, c1.Y, 2 * currRad, 2 * currRad); 
      using (Pen pen = new Pen(Color.White, 2)) 
       e.Graphics.DrawEllipse(pen, c1.X, c1.Y, 2 * currRad, 2 * currRad); 
      a++; 
     } 
    } 
    protected override void OnVisibleChanged(EventArgs e) 
    { 
     timer.Enabled = Visible; 
     base.OnVisibleChanged(e); 
    } 
} 

樣品2碼 - TransparentPictureBox代碼

using System; 
using System.Drawing; 
using System.Drawing.Drawing2D; 
using System.Linq; 
using System.Windows.Forms; 
class TransparentPictureBox : PictureBox 
{ 
    public TransparentPictureBox() 
    { 
     this.BackColor = Color.Transparent; 
    } 
    protected override void OnPaint(PaintEventArgs e) 
    { 
     if (Parent != null && this.BackColor == Color.Transparent) 
     { 
      using (var bmp = new Bitmap(Parent.Width, Parent.Height)) 
      { 
       Parent.Controls.Cast<Control>() 
         .Where(c => Parent.Controls.GetChildIndex(c) > Parent.Controls.GetChildIndex(this)) 
         .Where(c => c.Bounds.IntersectsWith(this.Bounds)) 
         .OrderByDescending(c => Parent.Controls.GetChildIndex(c)) 
         .ToList() 
         .ForEach(c => c.DrawToBitmap(bmp, c.Bounds)); 

       e.Graphics.DrawImage(bmp, -Left, -Top); 
      } 
     } 
     base.OnPaint(e); 
    } 
}