继续问GDI+,如何使画出的图不被控件覆盖 以前没做过这方面的,今天问个够。。我的窗体上本身是有控件的,我画的图的一些部分被控件遮盖了,我希望的是图遮盖控件。 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 很麻烦呀?要做的效果就是windows上一个窗口你拖动它的边缘时可以改变窗口大小呀,你看,windows上的就考虑遮盖部分了 放个picturebox,将picturebox置于这些控件上层,然后在里面画图就不会被这些控件挡住了 将picturebox置于这些控件上层?我托到那个控件上面去一个,运行,那个控件直接被覆盖。。 是这样的,我的窗体有一个listBox,现在我要在运行时可以用拖的方式改变它的大小,拖得时候会出现一个“虚矩形”也就是用GDI+画的一个图,可是这个矩形有些部分会被listBox遮挡住(例如,将listbox缩小时). 这样你画一个矩形框,长,宽比listbox刚好大 1 Pixel且置listBox下层即可,在listBox的SizeChanged事件里不断重绘这个矩形框 重载还是重写?为什么重写后不触发呀。。我写了一个类,继承listbox,仅仅重写了onpaint方法,但是不触发 你说的方法和我说的效果不一致呀,你开一个文件夹试试,你放大或缩小它,你仔细看看,它是在你mouseup那一刻才改变了窗口的大小 bool dragFlag = false; private void listBox1_MouseDown(object sender, MouseEventArgs e) { dragFlag = true; } private void listBox1_MouseMove(object sender, MouseEventArgs e) { if (dragFlag) { //画虚线框 } } private void listBox1_MouseUp(object sender, MouseEventArgs e) { dragFlag = false; } 如何画?我对GDI+一点不懂,今天才弄 private void listBox1_MouseMove( object sender, MouseEventArgs e ) { //if( isDraw ) //{ Pen p = new Pen( Color.Black, 1 ); p.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash; Bitmap bp = new Bitmap( pictureBox1.Width , pictureBox1.Height ); Graphics gp = Graphics.FromImage( bp ); gp.DrawRectangle( p, listBox1.Location.X - pictureBox1.Location.X-1, listBox1.Location.Y - pictureBox1.Location.Y-1, listBox1.Width + 1, listBox1.Height + 1 ); pictureBox1.Image = bp; //} } 这个功能有类.net支持ControlPaint的DrawReversibleFrame方法。参见:http://msdn.microsoft.com/zh-cn/library/system.windows.forms.controlpaint_members.aspx 将绘图的层次顺序确定为:控件在下,矩形框在上即可。简单的将就是先画控件,后画矩形框。方法如下:在form的paint事件里,先调用控件的paint事件,然后再调用画矩形框方法(不知道你这个封装了没有)。我做的一个绘图程序就有过类似的问题,画多个图形,图形之间有相互叠加的问题,我是通过将各图形进行排序,然后再按照顺序依次调用绘制方法解决的。 用这个方法画ControlPaint.DrawReversibleFrame具体去看这个帖子http://topic.csdn.net/u/20071220/17/d40930c4-93d8-41d8-8d64-28d744499ff7.html?2120318325 ControlPaint.DrawReversibleFrame的使用示例如下: Rectangle oldRect; private void listBox1_MouseMove(object sender, MouseEventArgs e) { ControlPaint.DrawReversibleFrame(oldRect,Color.Black, FrameStyle.Dashed); //坐标需要设置为屏幕坐标,自己调整吧。 oldRect = new Rectangle(this.listBox1.Location.X, this.listBox1.Location.Y, e.X, e.Y); ControlPaint.DrawReversibleFrame(oldRect, Color.Black, FrameStyle.Dashed); } private void listBox1_MouseDown(object sender, MouseEventArgs e) { oldRect = new Rectangle(this.listBox1.Location.X, this.listBox1.Location.Y, e.X, e.Y); ControlPaint.DrawReversibleFrame(oldRect, Color.Black, FrameStyle.Dashed); } private void listBox1_MouseUp(object sender, MouseEventArgs e) { ControlPaint.DrawReversibleFrame(oldRect, Color.Black, FrameStyle.Dashed); } 从用户坐标转化为屏幕坐标有个API函数。声明如下: [DllImport("user32.dll")] static extern bool ClientToScreen(IntPtr hWnd,ref Point lp); 自己计算的话注意标题栏尺寸,控件相对窗口的坐标是从标题栏下方计算的。 恩,我看MSDN上也是这样,在mousemove里调用了两次DrawReversibleFrame,这个令我很疑惑,我试了一下,如果调用一次,那么就会绘制出多个矩形,为什么调用两次就不会了呢? good good study ,day day up. ControlPaint.DrawReversibleFrame()用这个画,保证不会被覆盖而且框内会显示附上源代码,这是以前在网上找到的,分享给大家关键字: c# winform 鼠标 画 拉 虚线 框选 边框 效果 用鼠标画拖出来虚线框 只想单纯的画出一个矩形框 C#代码 1.using System; 2.using System.Collections.Generic; 3.using System.ComponentModel; 4.using System.Data; 5.using System.Drawing; 6.using System.Text; 7.using System.Windows.Forms; 8. 9.namespace AllTest 10.{ 11. public partial class Form11 : Form 12. { 13. bool MouseIsDown = false; 14. Rectangle MouseRect = Rectangle.Empty; 15. public Form11() 16. { 17. InitializeComponent(); 18. this.MouseDown += new MouseEventHandler(frmMain_MouseDown); 19. this.MouseMove += new MouseEventHandler(frmMain_MouseMove); 20. this.MouseUp += new MouseEventHandler(frmMain_MouseUp); 21. } 22. void frmMain_MouseUp(object sender, MouseEventArgs e) 23. { 24. this.Capture = false; 25. Cursor.Clip = Rectangle.Empty; 26. MouseIsDown = false; 27. DrawRectangle(); 28. MouseRect = Rectangle.Empty; 29. } 30. void frmMain_MouseMove(object sender, MouseEventArgs e) 31. { 32. if (MouseIsDown) 33. ResizeToRectangle(e.Location); 34. } 35. void frmMain_MouseDown(object sender, MouseEventArgs e) 36. { 37. MouseIsDown = true; 38. DrawStart(e.Location); 39. } 40. private void ResizeToRectangle(Point p) 41. { 42. DrawRectangle(); 43. MouseRect.Width = p.X - MouseRect.Left; 44. MouseRect.Height = p.Y - MouseRect.Top; 45. DrawRectangle(); 46. } 47. private void DrawRectangle() 48. { 49. Rectangle rect = this.RectangleToScreen(MouseRect); 50. ControlPaint.DrawReversibleFrame(rect, Color.White, FrameStyle.Dashed); 51. } 52. private void DrawStart(Point StartPoint) 53. { 54. this.Capture = true; 55. Cursor.Clip = this.RectangleToScreen(new Rectangle(0, 0, ClientSize.Width, ClientSize.Height)); 56. MouseRect = new Rectangle(StartPoint.X, StartPoint.Y, 0, 0); 57. } 58. } 59.} using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Text;using System.Windows.Forms;namespace AllTest{ public partial class Form11 : Form { bool MouseIsDown = false; Rectangle MouseRect = Rectangle.Empty; public Form11() { InitializeComponent(); this.MouseDown += new MouseEventHandler(frmMain_MouseDown); this.MouseMove += new MouseEventHandler(frmMain_MouseMove); this.MouseUp += new MouseEventHandler(frmMain_MouseUp); } void frmMain_MouseUp(object sender, MouseEventArgs e) { this.Capture = false; Cursor.Clip = Rectangle.Empty; MouseIsDown = false; DrawRectangle(); MouseRect = Rectangle.Empty; } void frmMain_MouseMove(object sender, MouseEventArgs e) { if (MouseIsDown) ResizeToRectangle(e.Location); } void frmMain_MouseDown(object sender, MouseEventArgs e) { MouseIsDown = true; DrawStart(e.Location); } private void ResizeToRectangle(Point p) { DrawRectangle(); MouseRect.Width = p.X - MouseRect.Left; MouseRect.Height = p.Y - MouseRect.Top; DrawRectangle(); } private void DrawRectangle() { Rectangle rect = this.RectangleToScreen(MouseRect); ControlPaint.DrawReversibleFrame(rect, Color.White, FrameStyle.Dashed); } private void DrawStart(Point StartPoint) { this.Capture = true; Cursor.Clip = this.RectangleToScreen(new Rectangle(0, 0, ClientSize.Width, ClientSize.Height)); MouseRect = new Rectangle(StartPoint.X, StartPoint.Y, 0, 0); } }}在鼠标按下事件里写(一定是鼠标按下事件MouseDown 因为我的参数e是鼠标数据对象 (不过你也可以传坐标)) MouseIsDown = true; DrawStart(e.Location); 在鼠标移动(MouseMove)事件里写 if (MouseIsDown) ResizeToRectangle(e.Location); 在鼠标释放(MouseUp)事件里写 this.Capture = false; Cursor.Clip = Rectangle.Empty; MouseIsDown = false; DrawRectangle(); MouseRect = Rectangle.Empty; 这样不会覆盖原来的控件,不会重绘控件 如果是加Panel的话 把DrawStart()方法里的Cursor.Clip = this.RectangleToScreen(this.Bounds); 改为Cursor.Clip = this.RectangleToScreen(this.panel1.ClientRectangle)); this.Capture = true;改为 this.panel1.Capture = true; MouseUp里的 this.Capture = false;改为 this.panel1.Capture = false; 这是设置鼠标筐选时鼠标的移动区域 和控件对鼠标的捕获 Cursor.Clip = this.RectangleToScreen(this.Bounds); 这是设置鼠标筐选时鼠标的移动区域 根据你的需要自己去设置 如果界面很简单的画,可以画在listBox的父级,比如窗体上绘制矩形。 IIS发布网站出错 广州一500强公司程序员面试题 服务器 和客户端响应问题 急急 谁知道flygoldfish (长江支流) MIS金质打印程序有一个严重的问题. C#水晶报表HTML文本格式解析img标签 用Visual C#.net进行wince开发,发觉combox和button没有keydown和keyup事件,怎么办? 后台修改页面的文本。 判断XML是否有某个节点 请问在winform下固定DataGrid的列用什么方法? C# 用smtp.163.com 发邮件,无发应问题。 C#智能设备如何显示图片 c# 读取资源文件
很麻烦呀?要做的效果就是windows上一个窗口你拖动它的边缘时可以改变窗口大小呀,你看,windows上的就考虑遮盖部分了
将picturebox置于这些控件上层?我托到那个控件上面去一个,运行,那个控件直接被覆盖。。
重载还是重写?为什么重写后不触发呀。。我写了一个类,继承listbox,仅仅重写了onpaint方法,但是不触发
你说的方法和我说的效果不一致呀,你开一个文件夹试试,你放大或缩小它,你仔细看看,它是在你mouseup那一刻才改变了窗口的大小
bool dragFlag = false;
private void listBox1_MouseDown(object sender, MouseEventArgs e)
{
dragFlag = true;
} private void listBox1_MouseMove(object sender, MouseEventArgs e)
{
if (dragFlag)
{
//画虚线框
}
} private void listBox1_MouseUp(object sender, MouseEventArgs e)
{
dragFlag = false;
}
{
//if( isDraw )
//{
Pen p = new Pen( Color.Black, 1 );
p.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
Bitmap bp = new Bitmap( pictureBox1.Width , pictureBox1.Height );
Graphics gp = Graphics.FromImage( bp );
gp.DrawRectangle( p, listBox1.Location.X - pictureBox1.Location.X-1, listBox1.Location.Y - pictureBox1.Location.Y-1, listBox1.Width + 1, listBox1.Height + 1 );
pictureBox1.Image = bp;
//}
}
ControlPaint的DrawReversibleFrame方法。
参见:http://msdn.microsoft.com/zh-cn/library/system.windows.forms.controlpaint_members.aspx
在form的paint事件里,先调用控件的paint事件,然后再调用画矩形框方法(不知道你这个封装了没有)。
我做的一个绘图程序就有过类似的问题,画多个图形,图形之间有相互叠加的问题,我是通过将各图形进行排序,然后再按照顺序依次调用绘制方法解决的。
http://topic.csdn.net/u/20071220/17/d40930c4-93d8-41d8-8d64-28d744499ff7.html?2120318325
{
ControlPaint.DrawReversibleFrame(oldRect,Color.Black, FrameStyle.Dashed);
//坐标需要设置为屏幕坐标,自己调整吧。
oldRect = new Rectangle(this.listBox1.Location.X, this.listBox1.Location.Y, e.X, e.Y);
ControlPaint.DrawReversibleFrame(oldRect, Color.Black, FrameStyle.Dashed);
} private void listBox1_MouseDown(object sender, MouseEventArgs e)
{
oldRect = new Rectangle(this.listBox1.Location.X, this.listBox1.Location.Y, e.X, e.Y);
ControlPaint.DrawReversibleFrame(oldRect, Color.Black, FrameStyle.Dashed);
} private void listBox1_MouseUp(object sender, MouseEventArgs e)
{
ControlPaint.DrawReversibleFrame(oldRect, Color.Black, FrameStyle.Dashed);
}
[DllImport("user32.dll")]
static extern bool ClientToScreen(IntPtr hWnd,ref Point lp); 自己计算的话注意标题栏尺寸,控件相对窗口的坐标是从标题栏下方计算的。
恩,我看MSDN上也是这样,在mousemove里调用了两次DrawReversibleFrame,这个令我很疑惑,我试了一下,如果调用一次,那么就会绘制出多个矩形,为什么调用两次就不会了呢?
用这个画,保证不会被覆盖
而且框内会显示
附上源代码,这是以前在网上找到的,分享给大家关键字: c# winform 鼠标 画 拉 虚线 框选 边框 效果
用鼠标画拖出来虚线框
只想单纯的画出一个矩形框
C#代码
1.using System;
2.using System.Collections.Generic;
3.using System.ComponentModel;
4.using System.Data;
5.using System.Drawing;
6.using System.Text;
7.using System.Windows.Forms;
8.
9.namespace AllTest
10.{
11. public partial class Form11 : Form
12. {
13. bool MouseIsDown = false;
14. Rectangle MouseRect = Rectangle.Empty;
15. public Form11()
16. {
17. InitializeComponent();
18. this.MouseDown += new MouseEventHandler(frmMain_MouseDown);
19. this.MouseMove += new MouseEventHandler(frmMain_MouseMove);
20. this.MouseUp += new MouseEventHandler(frmMain_MouseUp);
21. }
22. void frmMain_MouseUp(object sender, MouseEventArgs e)
23. {
24. this.Capture = false;
25. Cursor.Clip = Rectangle.Empty;
26. MouseIsDown = false;
27. DrawRectangle();
28. MouseRect = Rectangle.Empty;
29. }
30. void frmMain_MouseMove(object sender, MouseEventArgs e)
31. {
32. if (MouseIsDown)
33. ResizeToRectangle(e.Location);
34. }
35. void frmMain_MouseDown(object sender, MouseEventArgs e)
36. {
37. MouseIsDown = true;
38. DrawStart(e.Location);
39. }
40. private void ResizeToRectangle(Point p)
41. {
42. DrawRectangle();
43. MouseRect.Width = p.X - MouseRect.Left;
44. MouseRect.Height = p.Y - MouseRect.Top;
45. DrawRectangle();
46. }
47. private void DrawRectangle()
48. {
49. Rectangle rect = this.RectangleToScreen(MouseRect);
50. ControlPaint.DrawReversibleFrame(rect, Color.White, FrameStyle.Dashed);
51. }
52. private void DrawStart(Point StartPoint)
53. {
54. this.Capture = true;
55. Cursor.Clip = this.RectangleToScreen(new Rectangle(0, 0, ClientSize.Width, ClientSize.Height));
56. MouseRect = new Rectangle(StartPoint.X, StartPoint.Y, 0, 0);
57. }
58. }
59.}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;namespace AllTest
{
public partial class Form11 : Form
{
bool MouseIsDown = false;
Rectangle MouseRect = Rectangle.Empty;
public Form11()
{
InitializeComponent();
this.MouseDown += new MouseEventHandler(frmMain_MouseDown);
this.MouseMove += new MouseEventHandler(frmMain_MouseMove);
this.MouseUp += new MouseEventHandler(frmMain_MouseUp);
}
void frmMain_MouseUp(object sender, MouseEventArgs e)
{
this.Capture = false;
Cursor.Clip = Rectangle.Empty;
MouseIsDown = false;
DrawRectangle();
MouseRect = Rectangle.Empty;
}
void frmMain_MouseMove(object sender, MouseEventArgs e)
{
if (MouseIsDown)
ResizeToRectangle(e.Location);
}
void frmMain_MouseDown(object sender, MouseEventArgs e)
{
MouseIsDown = true;
DrawStart(e.Location);
}
private void ResizeToRectangle(Point p)
{
DrawRectangle();
MouseRect.Width = p.X - MouseRect.Left;
MouseRect.Height = p.Y - MouseRect.Top;
DrawRectangle();
}
private void DrawRectangle()
{
Rectangle rect = this.RectangleToScreen(MouseRect);
ControlPaint.DrawReversibleFrame(rect, Color.White, FrameStyle.Dashed);
}
private void DrawStart(Point StartPoint)
{
this.Capture = true;
Cursor.Clip = this.RectangleToScreen(new Rectangle(0, 0, ClientSize.Width, ClientSize.Height));
MouseRect = new Rectangle(StartPoint.X, StartPoint.Y, 0, 0);
}
}
}在鼠标按下事件里写(一定是鼠标按下事件MouseDown 因为我的参数e是鼠标数据对象
(不过你也可以传坐标))
MouseIsDown = true;
DrawStart(e.Location); 在鼠标移动(MouseMove)事件里写
if (MouseIsDown)
ResizeToRectangle(e.Location);
在鼠标释放(MouseUp)事件里写
this.Capture = false;
Cursor.Clip = Rectangle.Empty;
MouseIsDown = false;
DrawRectangle();
MouseRect = Rectangle.Empty; 这样不会覆盖原来的控件,不会重绘控件 如果是加Panel的话 把DrawStart()方法里的Cursor.Clip = this.RectangleToScreen(this.Bounds);
改为Cursor.Clip = this.RectangleToScreen(this.panel1.ClientRectangle));
this.Capture = true;改为 this.panel1.Capture = true;
MouseUp里的 this.Capture = false;改为
this.panel1.Capture = false; 这是设置鼠标筐选时鼠标的移动区域 和控件对鼠标的捕获
Cursor.Clip = this.RectangleToScreen(this.Bounds);
这是设置鼠标筐选时鼠标的移动区域 根据你的需要自己去设置