Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何设置所有者绘制控件的初始颜色 脚本_C#_.net_Winforms - Fatal编程技术网

C# 如何设置所有者绘制控件的初始颜色 脚本

C# 如何设置所有者绘制控件的初始颜色 脚本,c#,.net,winforms,C#,.net,Winforms,具有Windows窗体窗体派生窗体,其中包含面板派生控件: 表单将获得黑色背景颜色集: public MyForm() { InitializeComponent(); base.BackColor = Color.Black; } 并且面板控制被配置为双缓冲等,如所述,并且: 实际绘图是在MyPanel中的这些覆盖内完成的: protected override void OnPaintBackground(PaintEventArgs e) { e.Graphi

具有Windows窗体
窗体
派生窗体,其中包含
面板
派生控件:

表单将获得黑色背景颜色集:

public MyForm()
{
    InitializeComponent();

    base.BackColor = Color.Black;
}
并且面板控制被配置为双缓冲等,如所述,并且:

实际绘图是在
MyPanel
中的这些覆盖内完成的:

protected override void OnPaintBackground(PaintEventArgs e)
{
    e.Graphics.Clear(Color.Black);
}

protected override void OnPaint(PaintEventArgs e)
{
    e.Graphics.Clear(Color.Black);
}
错误行为 偶尔,当表单最初显示时,在实际调用我自己的绘图代码之前,我的所有者绘制的面板很快被绘制为白色:

调用我的绘图代码后,所有内容都正确绘制,我再也无法复制白色背景:

即使调整窗口和面板的大小也不会使其闪烁为白色

实施错误行为 如果我在窗体的
事件处理程序中设置睡眠,我可以强制执行面板的初始白色绘制:

private void MyForm_Shown(object sender, EventArgs e)
{
    Thread.Sleep(1000);
}
在调用我的所有者绘制的油漆代码之前,面板以白色显示1000毫秒

我的问题 在拥有所有者绘制/自定义绘制的面板时,如何避免初始白色显示

我的目标是让控件从一开始就“知道”其初始背景色(在我的示例中为黑色),而不是在最初显示之后

一些想法 我尝试过玩各种各样的东西,包括游戏,但没有明显的成功

我最初的想法是提供一些,但在深入研究之后,我仍然不知道这是否可行,是否会有所帮助

全部代码 为了安全起见,以下是我的全部代码

MyForm.cs:

public partial class MyForm : Form
{
    public MyForm()
    {
        InitializeComponent();

        base.BackColor = Color.Black;
    }

    private void MyForm_Shown(object sender, EventArgs e)
    {
        Thread.Sleep(1000);
    }
}
MyPanel.cs:

public class MyPanel : Panel
{
    public MyPanel()
    {
        base.DoubleBuffered = true;

        SetStyle(ControlStyles.AllPaintingInWmPaint, true);
        SetStyle(ControlStyles.ResizeRedraw, true);
        SetStyle(ControlStyles.UserPaint, true);
        SetStyle(ControlStyles.OptimizedDoubleBuffer, true);

        UpdateStyles();
    }

    protected override void OnPaintBackground(PaintEventArgs e)
    {
        e.Graphics.Clear(Color.Black);
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        e.Graphics.Clear(Color.Black);
    }
}

问题在于表单的背景,而不是面板的背景。窗体将在面板所在的位置有一个剪辑区域,直到它知道面板将自己绘制,因此最初不会绘制黑色。这是在windows窗体框架代码中完成的。能否将相同的样式应用于面板的父窗体?复制此样式的唯一方法是使父窗体消息队列保持忙碌。插入
线程睡眠(1000)事件中的code>将阻止在窗体上立即绘制任何控件,在窗体休眠时将其剪切区域保留为白色。例如,您可以将面板的可见性设置为
false
,并将其重新设置为
true
,作为显示的
事件中的最后一行。我不确定为什么它看起来是白色的。可能这只是内部容器中缺少颜色或VisualStyleRenderer操作的结果
Form.OnPaint
调用
base.OnPaint()
,其中base是
ContainerControl
,它调用
ScrollableControl
,它调用
Control
,而这不是公共对象。也许Hans知道背后的原因。评论“如果你不想要默认的Windows行为,你必须将
event.Handled
设置为true”很有趣,但显然为时已晚。另一个很有希望的方法是遵循文档中的100%透明形式,它可以避免大部分背景绘制,如果幸运的话,默认情况下也可以使用白色(因为透明并不意味着不能在onpaintbackground中绘制不透明矩形)如果将
allpaintingwmpaint
设置为
false
它将以黑色开始。我不确定这是否会破坏您的双缓冲目标,但您可以尝试一下,或许可以在重写的
WndProc()
中显式忽略WM_ERASEBKGND(第一个除外)。否则,我怀疑注册一个新类是一种方法,覆盖默认的背景颜色,否则就是“控制”。正如您所指出的,这是可行的,但相当痛苦()。
public class MyPanel : Panel
{
    public MyPanel()
    {
        base.DoubleBuffered = true;

        SetStyle(ControlStyles.AllPaintingInWmPaint, true);
        SetStyle(ControlStyles.ResizeRedraw, true);
        SetStyle(ControlStyles.UserPaint, true);
        SetStyle(ControlStyles.OptimizedDoubleBuffer, true);

        UpdateStyles();
    }

    protected override void OnPaintBackground(PaintEventArgs e)
    {
        e.Graphics.Clear(Color.Black);
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        e.Graphics.Clear(Color.Black);
    }
}