您的位置:首页 > 产品设计 > UI/UE

C#中实现真正的透明的PictrueBox

2011-07-26 10:58 751 查看
上一个项目中需要在一个图片上添加头发、装饰品。在实现过程中发现如下问题:

1、C#中的透明,只是对parent的透明,而对于parent上面的其他控件,完全忽略,这样如果后添加的空间又相互重叠,就会出现很奇怪的透明效果。

2、C#中添加控件时,最后添加的控件会出现在最下面。

一个比较资深的朋友告知,此类操作应该定义自己的数据结构,从而实现对图片的编辑和修改。听上去过于复杂的,时间上不允许,于是直接放弃了这个解决方案。到网上搜索,结果大都是同类问题,但是没有找到具体的解决方案,没有办法,只好动手写自己的控件,实现这一效果。

控件是PictureBox的子类,主要思路就是在控件的重绘方法中,遍历父控件的所有子控件,发现有其他子控件在改控件下面,并有重叠部分,画出重叠部分,如果发现有控件在改控件上面,调用Invalidate()方法,重画上面的控件。

代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Windows.Forms;

namespace VisualImage
{
public class TransparentPictureBox:PictureBox
{
protected override void OnPaint(PaintEventArgs e)
{
Graphics g = e.Graphics;
ControlCollection cc = this.Parent.Controls;
if (cc.Count > 1)
{
bool isUp = false;
for (int i = cc.Count - 1; i >= 0; i--)
{
Control c = cc[i];
if (isUp)
{
c.Invalidate();
}
else
{
drawRectangleIntersection(g, (TransparentPictureBox)c);
}

isUp = c == this;
}
}

Bitmap b = new Bitmap(Image);
g.DrawImage(b, 0, 0, b.Width, b.Height);
base.OnPaint(e);
}

protected void drawRectangleIntersection(Graphics g, TransparentPictureBox tpb)
{
Rectangle rectangle1 = new Rectangle(Location.X, Location.Y, Width, Height);
Rectangle rectangle2 = new Rectangle(tpb.Location.X, tpb.Location.Y, tpb.Width, tpb.Height);

if (rectangle1.IntersectsWith(rectangle2))
{
Rectangle rectangle3 = Rectangle.Intersect(rectangle1, rectangle2);
if (!rectangle3.IsEmpty)
{
Rectangle srcRect = new Rectangle(rectangle3.Location.X - tpb.Location.X, rectangle3.Location.Y - tpb.Location.Y, rectangle3.Width, rectangle3.Height);
Rectangle destRect = new Rectangle(Math.Abs(Location.X - rectangle3.Location.X), Math.Abs(Location.Y - rectangle3.Location.Y), rectangle3.Width, rectangle3.Height);
g.DrawImage(tpb.Image, destRect, srcRect, GraphicsUnit.Pixel);
}
}
}
}
}

改控件只实现了重叠部分的重画,至于将后放置的控件放在父控件的最上层,还需要额外的处理。

使用上述控件代码如下:

private void decorationPBMouseDown(object sender, MouseEventArgs e)
{
mouse_offset = new Point(-e.X, -e.Y);
beginDrag = true;
}
private void decorationPBMouseUp(object sender, MouseEventArgs e)
{
beginDrag = false;
}

private void decorationPBMouseMove(object sender, MouseEventArgs e)
{
if (beginDrag)
{
Point mousePos = Control.MousePosition;
mousePos.Offset(mouse_offset.X, mouse_offset.Y);//设置偏移
((Control)sender).Location = ((Control)sender).Parent.PointToClient(mousePos);
draged = true;
}

}

private void button2_Click(object sender, EventArgs e)
{
Bitmap image = new Bitmap("hair image location");
this.SuspendLayout();
TransparentPictureBox pb = new TransparentPictureBox();
pb.SizeMode = PictureBoxSizeMode.AutoSize;
Bitmap temp = new Bitmap(image, 138, image.Height * 138 / image.Width);
pb.BackColor = Color.Transparent;
pb.Image = temp;

pb.Location = new Point(200, 60);
List<Control> tempList = new List<Control>();
List<Point> tempLocations = new List<Point>();
for (int i = 0; i < pictureBox.Controls.Count; i++)
{
tempLocations.Add(pictureBox.Controls[i].Location);
tempList.Add(pictureBox.Controls[i]);
}
this.pictureBox.Controls.Clear();
this.pictureBox.Controls.Add(pb);
for (int i = 0; i < tempList.Count; i++)
{
this.pictureBox.Controls.Add(tempList[i]);
tempList[i].Location = tempLocations[i];
}
this.ResumeLayout(false);
pb.MouseDown += decorationPBMouseDown;
pb.MouseMove += decorationPBMouseMove;
pb.MouseUp += decorationPBMouseUp;
}

控件下载地址:http://download.csdn.net/source/3469956
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: