.NET Compact Framework中的透明控件实现

在开发.NET Compact Framework应用程序时,经常需要在表单背景上添加图像。然而,标准的标签控件和其他控件并不支持透明背景。为了解决这个问题,需要创建自定义的用户控件。本文将介绍如何实现这一功能。

在最近的一个.NET Compact Framework项目中,需要在表单背景上添加一张图片。通过观看微软的视频教程实现了这一点。但是,视频也告诉.NET Compact Framework中的标签控件不支持透明背景。因此,需要创建自己的用户控件。找到了一篇很好的文章,由Per Ola Sæther撰写的《在.NET Compact Framework中创建具有透明标签的渐变背景》,它帮助找到了解决方案。

使用代码

创建透明控件的基本思想是重写控件的OnPaintBackgound方法,使其调用父表单的OnPaintBackgound来绘制背景,然后在其上绘制控件的内容。

首先,创建了与文章中介绍的相同的接口。

public interface IPaintControl { void InvokePaintBackground(PaintEventArgs e); }

然后,创建了一个基表单,这样就不必为每个表单编写相同的代码。

public class CcForm : Form, IPaintControl { public virtual void InvokePaintBackground(PaintEventArgs e) { OnPaintBackground(e); } }

创建一个基控件,这样不仅可以有透明标签,还可以有其他类型的控件,如单选按钮和复选框。它有一个名为TransparentBackground的属性。如果出于某种原因不希望控件透明,可以更改此属性。在OnPaintBackground方法中,它调用其父级的InvokePaintBackground来绘制背景。

public class CcTransparentControl : Control { private bool _transparentBackgound = true; public bool TransparentBackground { get { return _transparentBackgound; } set { _transparentBackgound = value; } } protected override void OnPaintBackground(PaintEventArgs e) { if (_transparentBackgound) { IPaintControl parent = Parent as IPaintControl; if (parent != null) { parent.InvokePaintBackground(e); } } else { base.OnPaintBackground(e); } } }

现在可以使用以下代码创建透明标签控件:

public class CcTransparentLabel : CcTransparentControl { private ContentAlignment textAlign = ContentAlignment.TopLeft; public ContentAlignment TextAlign { get { return textAlign; } set { textAlign = value; } } public CcTransparentLabel() { } protected override void OnPaint(PaintEventArgs e) { Graphics gfx = e.Graphics; if (this.TextAlign == ContentAlignment.TopLeft) { gfx.DrawString(this.Text, this.Font, new SolidBrush(this.ForeColor), ClientRectangle); } else if (this.TextAlign == ContentAlignment.TopCenter) { SizeF size = gfx.MeasureString(this.Text, this.Font); int left = this.Width / 2 - (int)size.Width / 2; var rect = new Rectangle(ClientRectangle.Left + left, ClientRectangle.Top, (int)size.Width, ClientRectangle.Height); gfx.DrawString(this.Text, this.Font, new SolidBrush(this.ForeColor), rect); } else if (this.TextAlign == ContentAlignment.TopRight) { SizeF size = gfx.MeasureString(this.Text, this.Font); int left = this.Width - (int)size.Width + this.Left; var rect = new Rectangle(ClientRectangle.Left + left, ClientRectangle.Top, (int)size.Width, ClientRectangle.Height); gfx.DrawString(this.Text, this.Font, new SolidBrush(this.ForeColor), rect); } } }

在表单中,将表单更改为继承自CcForm,并将CcTransparentLabel拖放到其中。

public partial class FormWithSolidColorBackground : CcForm

以下是屏幕截图。如所见,标签现在具有透明背景。

然而,当尝试添加具有渐变颜色的图像背景时,标签看起来不再正确。要了解问题,首先需要看看如何在表单上显示背景图像

public partial class FormWithImageBackground : CcForm { private Rectangle _backgroundRect; private Bitmap _background; private string currentPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetName().CodeBase.ToString()); public FormWithImageBackground() { InitializeComponent(); _background = new Bitmap(currentPath + @"\ImageBackground.jpg"); _backgroundRect = new Rectangle(0, 0, _background.Width, _background.Height); } protected override void OnPaintBackground(PaintEventArgs e) { Graphics g = e.Graphics; g.DrawImage(_background, this.ClientRectangle, _backgroundRect, GraphicsUnit.Pixel); } }

发生的情况是,当透明标签控件调用OnPaintBackground时,它会在标签控件内重新绘制图像。因此,它在标签的背景上显示了图像的左上角。为了解决这个问题,将标签控件的位置传递给表单,并使用它来重新绘制图像。例如,如果标签位于(10, 20),则图像背景将在(-10, -20)处显示。这可能不是最好的解决方案,但它简单且有效。以下是修订后的接口和控件。

public interface IPaintControl { void InvokePaintBackground(PaintEventArgs e, Point location); } public class CcForm : Form, IPaintControl { public virtual void InvokePaintBackground(PaintEventArgs e, Point location) { OnPaintBackground(e); } } public class CcTransparentControl : Control { .... protected override void OnPaintBackground(PaintEventArgs e) { if (_transparentBackgound) { IPaintControl parent = Parent as IPaintControl; if (parent != null) { parent.InvokePaintBackground(e, this.Location); } } else { base.OnPaintBackground(e); } } }

在表单中,然后覆盖InvokePaintBackground方法以在所需位置绘制图像。

public override void InvokePaintBackground(System.Windows.Forms.PaintEventArgs e, System.Drawing.Point location) { Graphics g = e.Graphics; Rectangle destRect = new Rectangle(-1 * location.X, -1 * location.Y, ClientRectangle.Width, ClientRectangle.Height); g.DrawImage(_background, destRect, _backgroundRect, GraphicsUnit.Pixel); }

现在有了一个图像背景上的透明标签。

透明单选按钮和复选框控件

还创建了透明的单选按钮和复选框控件。这些是表单中常用的控件,Panel控件也是如此。以下示例显示了透明单选按钮和复选框在透明面板上的效果。

祝编程愉快!

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485