【发布时间】:2016-11-17 21:04:27
【问题描述】:
我正在尝试实现一个“可填写表单”,其中可编辑的文本字段出现在点阵打印机的预打印表单图像的顶部。 (使用 c# 和 Windows 窗体并以 .Net 2.0 为目标)我的第一个想法是使用图像作为 Windows 窗体背景,但滚动时看起来很糟糕,而且内容也无法正确滚动。
我的下一个尝试是创建一个固定大小的窗口,该窗口带有一个超出窗口边界的面板(用于滚动目的)。我在面板中添加了一个 PictureBox,并在其顶部添加了我的文本框。这工作正常,除了 TextBoxes 不支持透明度,所以我尝试了几种方法使 TextBoxes 透明。一种方法是使用奇怪的背景颜色和透明度键。另一个,在以下链接中描述,是创建一个允许透明度的派生类:
Transparency for windows forms textbox
TextBox with a Transparent Background
这两种方法都不起作用,因为我发现,Windows 窗体中的“透明度”只是意味着窗口的背景被绘制到控件背景上。由于 PictureBox 位于 Window 背景和 TextBox 之间,因此它看起来 TextBox 不透明,而只是具有与 Window 的背景颜色相同的背景颜色。使用透明键方法,整个应用程序变得透明,以便您可以在后台看到 Visual Studio,这不是我想要的。所以现在我正在尝试实现一个派生自 TextBox 并覆盖 OnPaint 或 OnPaintBackground 的类,以将 PictureBox 图像的适当部分绘制到控件背景上,以提供透明度错觉,如下面的链接所述:
How to create a transparent control which works when on top of other controls?
首先,我无法让它工作(我尝试了各种方法,要么得到一个完全黑色的控件,要么只是一个标准的标签背景),其次,我从 DrawToBitmap 方法中得到间歇性 ArgumentExceptions有神秘消息“附加信息:targetBounds”。根据 MSDN 的以下链接,我认为这是因为位图太大 - 无论哪种情况,在这里捕获整个表单图像似乎效率低下,因为我真的只想要它的一小部分。
https://msdn.microsoft.com/en-us/library/system.windows.forms.control.drawtobitmap(v=vs.100).aspx
这是我最近的尝试。有人可以帮我实现 OnPaintBackground 或提出不同的方法吗?提前致谢!
public partial class TransparentTextbox : TextBox
{
public TransparentTextbox()
{
InitializeComponent();
SetStyle(ControlStyles.OptimizedDoubleBuffer |
ControlStyles.AllPaintingInWmPaint |
ControlStyles.ResizeRedraw |
ControlStyles.UserPaint, true);
}
protected override void OnPaintBackground(PaintEventArgs e)
{
//base.OnPaintBackground(e); // not sure whether I need this
if (Parent != null)
{
foreach (Control c in Parent.Controls)
{
if (c.GetType() == typeof(PictureBox))
{
PictureBox formImg = (PictureBox)c;
Bitmap bitmap = new Bitmap(formImg.Width, formImg.Height);
formImg.DrawToBitmap(bitmap, formImg.Bounds);
e.Graphics.DrawImage(bitmap, -Left, -Top);
break;
}
}
Debug.WriteLine(Name + " didn't find the PictureBox.");
}
}
}
注意:这已被标记为重复,但我在原始帖子中引用了“重复问题”,并解释了它为什么不起作用。该解决方案仅在文本框直接位于窗口上方时才有效 - 如果另一个控件(例如我的面板和图片框)位于窗口和文本框之间,则 .Net 将窗口背景绘制到文本框背景上,有效地使其背景看起来是灰色的,不透明。
【问题讨论】:
-
我认为这对于 Windows 窗体标准文本框是不可能的。如果您愿意使用第 3 方套件(我可以推荐),Infragistics 使用背景图像和来源为您的问题提供解决方案。 infragistics.com/community/forums/t/1324.aspx
-
这是 Windows 窗体中的一个限制,一些 3rd 方组件几乎可以修复。但它会增加大量的重量和对简单 Winforms 项目的引用。切换到 WPF 是不可能的吗?像这样的东西很容易适应。
-
@Reza - 这看起来很有希望 - 示例应用程序基本上正在做我想做的事情。仅包括源代码并将我的透明文本框更改为他的控件之一,就可以得到与我自己的课程相似的结果,但我将深入挖掘 - 如果他的作品,我一定会遗漏一些东西。
-
@KevinBBurns - 我正在尝试制作一个可以在较新的 WPF 应用程序和较旧的 WinForms 应用程序之间共享的类库......我很确定我可以让 WPF 解决方案正常工作,但是一种或另一种我需要使用它的主要地方是在现有的 WinForms 应用程序中。