C# 孩子继承父母的外貌

C# 孩子继承父母的外貌,c#,winforms,custom-controls,containers,onpaint,C#,Winforms,Custom Controls,Containers,Onpaint,我已经创建了一个简单的自定义面板作为我的基础。我添加了自定义属性来创建边框和渐变背景。如果覆盖OnPaint和OnPaintBackground,则父控件的所有子控件将继承渐变和边框样式。作为一个解决方案,我使用了parents BackgroundImage属性,该属性工作良好,但有一些随机的怪癖。必须有更好的方法来处理这个问题,但我没有找到解决办法。是否有任何通过Interop或其他C#方法实现的窗口API函数可以解决此问题?如果是,请提供一个例子 编辑下面是正在复制的样式(示例很难看,但说

我已经创建了一个简单的自定义面板作为我的基础。我添加了自定义属性来创建边框和渐变背景。如果覆盖OnPaint和OnPaintBackground,则父控件的所有子控件将继承渐变和边框样式。作为一个解决方案,我使用了parents BackgroundImage属性,该属性工作良好,但有一些随机的怪癖。必须有更好的方法来处理这个问题,但我没有找到解决办法。是否有任何通过Interop或其他C#方法实现的窗口API函数可以解决此问题?如果是,请提供一个例子

编辑下面是正在复制的样式(示例很难看,但说明了问题):

编辑2这里是一个简单的硬编码容器控件,没有所有属性、设计器属性等

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 );
        }
    }
}

初始化控件创建/加载时的属性


然后“使控件无效”以强制重新绘制控件

我无法在我的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);
    } 
}
结果是:


如果创建的
标签
控件的
BackColor
属性设置为
Color.Transparent
,则它将调用其父控件的
OnPaintBackground()
实现

如果您修改Jon的示例如下:

var label = new Label { 
    Text = "Label",
    Location = new Point(20, 50),
    BackColor = Color.Transparent
};
然后你将复制这个问题

然而,有一个简单的解决办法。问题来自于创建线性渐变笔刷的方式。由于要将
e.ClipRectangle
传递给其构造函数,因此渐变的形状将根据渲染的控件(容器或标签)而有所不同。另一方面,如果你经过容器的底部,那么渐变将始终具有相同的形状,结果应该是你想要的:

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


这不起作用。集装箱控制中心的所有子项都用父项梯度重新绘制。如果将子控件背景设置为透明,则不希望复制父容器控件的样式。如果将子控件背景设置为透明,则父控件样式将显示。。。这就是它的工作原理。。。除非你想要一个特定的背景。。。在这种情况下,指定它(白色示例)您是否将容器放在另一个容器中?是的,我希望它真正透明。。。不是“嘿”将其设置为“透明”,而是来自Microsoft:嘿!那没有道理!让它继承它的父对象!谁需要透明度!!!哈哈哈,真有趣,我认为这不应该发生。你能发布你的
OnPaint()
OnPaintBackground()
覆盖吗?
label2
是一个标准的
Label
控件还是另一个自定义控件?在你将它们拖动/添加到容器中之后,你会立即对子控件产生这种效果吗,或者在您将子控件的背景设置为透明后?我一直在苦苦思索为什么我的子控件使用与窗体相同的边框进行绘制,这是因为它们是透明的。我只是将它们设置为与表单相同的背景颜色,然后为我排序。很高兴你发布了这个!(在圆角表单上工作,我的按钮/图像框以相同的边框结束)