2012-08-17 98 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