首页 > 解决方案 > 控制如何、何时以及是否绘制子控件 (.NET)

问题描述

我正在.NET 中编写一个具有插件接口的应用程序。该插件界面提供了几种将信息(控件)绘制到应用程序窗口表面的方法。虽然我这样做有几个原因,但主要原因是通过使用图形或直接根据背景颜色操纵文本颜色,为文本提供自定义着色。我通过使用“文本蒙版”来做到这一点,这是一个黑白位图,用作“alpha”贴图,让 Paint 方法知道在哪里应用纹理/颜色更改。

插件开发人员可以选择使用常规文本(例如带有标签)、掩码文本(绘制到掩码上而不是作为常规控件),或者让用户决定。为此,我提供了一个修改后的标签类,它可以“正常”绘制(当没有为控件设置文本掩码时),也可以在用户或开发人员决定时绘制到文本掩码(取决于插件开发人员希望提供给用户)。这是该类的代码,以便您了解这是如何完成的:

public class MaskingLabel : Label
{
    private static readonly SolidBrush maskBrush = new SolidBrush(Color.White);
    public Bitmap Mask { get; set; }
    public MaskingLabel() : base() { }
    protected override void OnPaint(PaintEventArgs e)
    {
        if (Mask == null)   
            base.OnPaint(e);
        else
        {
            Graphics g = Graphics.FromImage(Mask);
            g.DrawString(Text, Font, maskBrush, Location);
        }
    }
}

我遇到的问题是这种方法要求我以非常特定的顺序处理控件,以便正确绘制表单。我需要找到最有效的方法来按照给定的顺序完成下面列出的任务。我已经想到了进一步讨论的三种可能性。作为参考,这是必须完成任务的顺序:

  1. 必须首先绘制所有将位图对象设置为蒙版的“MaskingLabel”控件,以便在下一步之前创建蒙版。
  2. 蒙版应用于背景图片。
  3. 生成的位图的绘制方式与绘制背景的方式相似(除了首先对其进行修改)。
  4. 其余控件正常绘制。

有没有办法让我确保在不手动分离控件的情况下发生这种情况?我的第一个猜测是否定的。因此,我在下面有一些关于我应该如何去做的猜测。我希望对 GDI+ 有更深入了解的人可以提供一些见解。

  1. 我想到的一个想法是在 OnPaintBackground 方法期间绘制蒙版控件。但是,我不想通过两次绘制控件来浪费时间。这意味着我需要过滤掉在主 Paint 方法中绘制了哪些控件,这有效地引导我们选择选项 2(FAIK):
  2. 我可以手动过滤掉绘制到蒙版的控件,这样它们就不会被添加到控件中。我的问题是他们会被吸引吗?我可以手动强制他们调用 OnPaint 方法吗?
  3. 如果这样做不起作用,那么也许我可以创建一个单独的派生面板控件作为“背景”子控件,充当可以强制首先绘制的背景图片?

编辑(部分答案):发布后我意识到我已经在我的项目中内置了部分解决方案。尽管如此,我认为这是一个合理的问题,所以如果有人可以在我在下面的描述中所做的之外添加更多见解,欢迎提出。

具体来说,我的项目只有两个添加到“根”表单的控件:一个位于顶部的栏(显示时停靠在顶部),以及一个占据其余空间的透明面板(带有停靠样式设置为填充)。所以我的解决方案是将掩码控件添加到主窗体并将所有其余部分添加到面板中。 这只剩下一个待解决的问题:如何确保最后绘制面板和栏?(作为第一个列表中第 4 步的一部分?)

标签: c#.netwinformscontrolsgdi+

解决方案


推荐阅读