2012-08-17 95 views
4

我用ContainerControl作爲我的基礎創建了一個簡單的自定義面板。我已經添加了自定義屬性來創建邊框和漸變背景。如果我重寫OnPaint和OnPaintBackground父級的所有子控件都繼承漸變和邊框樣式。作爲一項解決方案,我使用父母的BackgroundImage屬性,它工作正常,但有一些隨機怪癖。必須有更好的方法來解決這個問題,但我沒有找到解決辦法。有沒有通過Interop或其他C#方法來解決這個問題的窗口API函數?如果是這樣,請提供一個例子。孩子們繼承父母的外貌

編輯!這裏是被複制的樣式(例如難看,但使點):

enter image description here

EDIT 2!這裏是沒有所有的性能的簡單的硬編碼一個ContainerControl,設計師屬性等

public class Container : ContainerControl 
{ 
    protected override void OnPaintBackground(PaintEventArgs e) 
    { 
     using (var brush = new LinearGradientBrush(e.ClipRectangle, Color.Red, Color.Blue, LinearGradientMode.Vertical)) 
     { 
      e.Graphics.FillRectangle(brush, e.ClipRectangle); 
     } 
    } 
} 
+0

有趣的是,我不認爲這會發生。你可以發佈你的'OnPaint()'和'OnPaintBackground()'覆蓋嗎? – 2012-08-21 19:12:26

+0

發佈圖片。 – 2012-08-21 19:15:25

+0

'label2'是標準'Label'控件還是另一個自定義控件? – 2012-08-21 19:19:54

回答

2

如果Label控制其BackColor屬性設置爲Color.Transparent創建的,它最終會調用其父OnPaintBackground()實現。

如果你修改了喬恩的例子是這樣的:

var label = new Label { 
    Text = "Label", 
    Location = new Point(20, 50), 
    BackColor = Color.Transparent 
}; 

然後你會重現該問題。

但是,有一個簡單的解決方法。問題來自您創建線性漸變畫筆的方式。由於您將e.ClipRectangle傳遞給其構造函數,因此漸變的形狀將根據呈現的控件(容器或標籤)而變化。在另一方面,如果你通過容器的ClientRectangle,則漸變將始終具有相同的形狀,其結果應該是你在找什麼:

protected override void OnPaintBackground(PaintEventArgs e) 
{ 
    using (var brush = new LinearGradientBrush(ClientRectangle, 
      Color.Red, Color.Blue, LinearGradientMode.Vertical)) { 
     e.Graphics.FillRectangle(brush, e.ClipRectangle); 
    } 
} 

結果是:

enter image description here

+0

你真是個天才! – 2012-08-23 13:05:41

0

初始化性質上控制創建/負載

然後「INVALIDATE」控制以強制重繪控制

+0

這沒有奏效。 ContainerControl的所有子項都用父梯度重繪。如果我將子控件背景設置爲透明,我不希望複製父容器的樣式。 – 2012-08-21 19:05:40

+0

如果您將子控件背景設置爲透明,則父控件樣式將顯示...它是如何工作的...除非您想要特定背景...在這種情況下指定它(例如白色) – ullfindsmit 2012-08-21 19:17:53

+0

是你嗎把容器放在另一個容器內? – ullfindsmit 2012-08-21 19:18:29

0

我無法在Windows 7機器上簡單地重現此內容 - 這表明它可能是您在設計器中設置的屬性之一。簡短但完整的程序:

using System; 
using System.Drawing; 
using System.Drawing.Drawing2D; 
using System.Windows.Forms; 

public class GradientContainer : ContainerControl 
{ 
    protected override void OnPaintBackground(PaintEventArgs e) 
    { 
     using (var brush = new LinearGradientBrush(e.ClipRectangle, 
         Color.Red, Color.Blue, LinearGradientMode.Vertical)) 
     { 
      e.Graphics.FillRectangle(brush, e.ClipRectangle); 
     } 
    } 
} 

class Test 
{ 
    static void Main() 
    { 
     var label = new Label { 
      Text = "Label", 
      Location = new Point(20, 50) 
     }; 
     var container = new GradientContainer { 
      Size = new Size(200, 200), 
      Location = new Point(0, 0), 
      Controls = { label } 
     };   

     Form form = new Form { 
      Controls = { container }, 
      Size = new Size(300, 300) 
     }; 
     Application.Run(form); 
    } 
} 

而結果:

Label has no gradient