Way*_*pps 7 compact-framework .net-cf-3.5
我一直在尝试显示一个透明边框作为控件背景的图像.
不幸的是,透明区域在父窗体中创建了一个洞,如下所示:

在上面的图像中,表格有一个红色背景,我希望在透明区域中看到我的控制.
我使用的代码如下:
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
if (this.Image != null)
{
Graphics g = Graphics.FromImage(this.Image);
ImageAttributes attr = new ImageAttributes();
//set the transparency based on the top left pixel
attr.SetColorKey((this.Image as Bitmap).GetPixel(0, 0), (this.Image as Bitmap).GetPixel(0, 0));
//draw the image using the image attributes.
Rectangle dstRect = new Rectangle(0, 0, this.Image.Width, this.Image.Height);
e.Graphics.DrawImage(this.Image, dstRect, 0, 0, this.Image.Width, this.Image.Height,
GraphicsUnit.Pixel, attr);
}
else
{
base.OnPaint(e);
}
}
protected override void OnPaintBackground(System.Windows.Forms.PaintEventArgs e)
{
//base.OnPaintBackground(e);
}
Run Code Online (Sandbox Code Playgroud)
这个类继承自PictureBox,因为我需要一个实现OnMouseMove和OnMouseUp Events的控件.
我一直在研究大部分时间而没有成功测试出不同的想法,但不幸的是,大部分只能在完整的框架上工作而不是.Net CF.
任何想法将不胜感激.
啊CF透明度的乐趣啊.我可以继续谈论它(并在我的博客和我很久以前做过的Project Resistance代码).
要点就是这个.子控件必须绘制它的区域,但首先它必须回调它的父级(在你的情况下为Form)并告诉它除了在孩子的剪辑区域之外的任何地方重绘它的背景图像然后在它之上绘制它自己.如果这听起来有点令人困惑,那是因为它是.
例如,如果你看一下Project Resistance,一个View(它只是一个Control)会绘制一个电阻和波段.它位于具有图像背景的Form中,并且该背景需要"透过"电阻器的透明区域:

因此,在电阻器的绘图代码中,它执行此操作:
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
try
{
RECT rect = new RECT(this.Bounds);
// draw the blank
Infrastructure.GraphicTools.DrawTransparentBitmap(e.Graphics, m_blankImage, Bounds,
new Rectangle(0, 0, m_blankImage.Width, m_blankImage.Height));
if (m_bandsImage != null)
{
// draw the bands
Infrastructure.GraphicTools.DrawTransparentBitmap(e.Graphics, m_bandsImage, Bounds,
new Rectangle(0, 0, m_bandsImage.Width, m_bandsImage.Height));
}
}
finally
{
}
if (!Controller.TouchMode)
{
// TODO: draw in the selection arrow
// Controller.SelectedBand
}
}
Run Code Online (Sandbox Code Playgroud)
这很简单.关键是它调用它的基础OnPaint,它执行此操作:
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
// this assumes we're in a workspace, on MainForm (the whole Parent.Parent thing)
IBackgroundPaintProvider bgPaintProvider = Parent.Parent as IBackgroundPaintProvider;
if (bgPaintProvider != null)
{
Rectangle rcPaint = e.ClipRectangle;
// use the parent, since it's the workspace position in the Form we want,
// not our position in the workspace
rcPaint.Offset(Parent.Left, Parent.Top);
bgPaintProvider.PaintBackground(e.Graphics, e.ClipRectangle, rcPaint);
}
}
Run Code Online (Sandbox Code Playgroud)
你可以看到它正在调用PaintBackground包含的Form(在这种情况下它是Parent.Parent,因为Control实际上是在一个名为Workspace的容器中 - 你不需要在你的情况下走两次).这会将您目前看到的区域中的背景图像绘制为"洞"
public void PaintBackground(Graphics g, Rectangle targetRect, Rectangle sourceRect)
{
g.DrawImage(m_bmBuffer, targetRect, sourceRect, GraphicsUnit.Pixel);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2263 次 |
| 最近记录: |