2012-02-21 42 views
3

早上,Winforms:一个可拖动的透明矩形

我只是准备好在这一点上挖出我自己的眼睛。我正在.NET 3.5上使用Windows窗体构建一个基本的图像编辑器,我需要的是一个“选择工具”。这个工具需要在点击一个按钮时出现,并且将是一个固定大小,它需要是一个具有透明中心的拖拽式矩形。

这样做的目的是几乎像一个“图片框架”,因为用户可以将矩形拖放到图像的一部分上,然后点击另一个按钮以快照当前矩形内的任何按钮。 (请注意:我不想要一个橡皮筋矩形,它必须是一个固定的大小,可拖动的形式和透明)。

我已经花了两天时间在网上搜寻,本网站正在寻找可能的解决方案,其中没有任何使用。我设法使控件可以拖动 - 但这会带来透明度方面的问题。下面是使控件可拖动的代码,但我不确定这是正确的路径。

class ControlMover 
{ 
    public enum Direction 
    { 
     Any, 
     Horizontal, 
     Vertical 
    } 

    public static void Init(Control control) 
    { 
     Init(control, Direction.Any); 
    } 

    public static void Init(Control control, Direction direction) 
    { 
     Init(control, control, direction); 
    } 

    public static void Init(Control control, Control container, Direction direction) 
    { 
     EditorForm.blnSelectArea = true; 
     bool Dragging = false; 
     Point DragStart = Point.Empty; 
     control.MouseDown += delegate(object sender, MouseEventArgs e) 
     { 
      Dragging = true; 
      DragStart = new Point(e.X, e.Y); 
      control.Capture = true; 
     }; 
     control.MouseUp += delegate(object sender, MouseEventArgs e) 
     { 
      Dragging = false; 
      control.Capture = false; 
     }; 
     control.MouseMove += delegate(object sender, MouseEventArgs e) 
     { 
      if (Dragging) 
      { 
       if (direction != Direction.Vertical) 
        container.Left = Math.Max(0, e.X + container.Left - DragStart.X); 
       if (direction != Direction.Horizontal) 
        container.Top = Math.Max(0, e.Y + container.Top - DragStart.Y); 

       control.Invalidate(); 

      } 
     }; 
    } 
} 

任何人都可以指向正确的方向或建议去哪里寻找。

非常感谢

回答

6

我actualy提出了屏幕捕获的aplication是:工作的描述你的方式,使它可拖动我使用鼠标事件。为了让它透明,我只是用半透明PNG图像作为背景图像做了另一个Form控件。

public partial class Photo : Form 
    { 
     public delegate void ScreenShotReadyDelegate(Bitmap g); 
     public event ScreenShotReadyDelegate ScreenShotReady; 

     bool Moving = false; 
     Point oldLoc = new Point(); 

     public Photo() 
     { 
      InitializeComponent(); 
      this.FormBorderStyle = FormBorderStyle.None; 
      this.DoubleBuffered = true; 
      this.SetStyle(ControlStyles.ResizeRedraw, true); 
     } 

     private void Photo_MouseDoubleClick(object sender, MouseEventArgs e) 
     { 
      this.BackgroundImage = null; 
      this.Invalidate(); 
      Rectangle bounds = this.Bounds; 
      using (Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height)) 
      { 
       using (Graphics g = Graphics.FromImage(bitmap)) 
       { 
        g.CopyFromScreen(new Point(bounds.Left, bounds.Top), Point.Empty, bounds.Size); 
       } 
       ScreenShotReady(bitmap); 
      } 
      this.BackgroundImage = Properties.Resources.rect; 
      this.Invalidate(); 
     } 

     private void Photo_MouseDown(object sender, MouseEventArgs e) 
     { 
      this.Moving = true; 
      this.oldLoc = MousePosition; 
     } 

     private void Photo_MouseMove(object sender, MouseEventArgs e) 
     { 
      if (this.Moving) 
      { 
       Point vector = new Point(MousePosition.X - this.oldLoc.X, MousePosition.Y - this.oldLoc.Y); 
       this.Location = new Point(this.Location.X + vector.X, this.Location.Y + vector.Y); 
       this.oldLoc = MousePosition; 
      } 
     } 

     private void Photo_MouseUp(object sender, MouseEventArgs e) 
     { 
      this.Moving = false; 
     } 
    } 
+0

这就是我正在努力,并即将建议。你做了我想说的话。 +1 – Maheep 2012-02-21 09:31:43

+0

优秀的,毕竟我的眼睛可能会留在他们的口袋里!非常感谢! – 2012-02-21 09:35:01

+0

那么'rect'是你的透明背景图片吗? – 2012-02-21 09:52:01

2

你应该能够阅读本Painting On Top Of Child Controls

后,我以前用过ControlPaint.DrawReversibleFrame(_FrameRect, Color.Black, FrameStyle.Dashed);自己和它工作得很好:)

+0

我很欣赏你的答案,但是这是一个非拖动橡皮筋矩形。我正在寻找一个矩形,我可以设置为一个固定的大小,然后点击并拖动页面。为努力欢呼。 – 2012-02-21 09:23:03

+2

我的不好。我会再读一遍,如果我得到答案,就回来。 – radbyx 2012-02-21 09:24:53

+1

如果您第一次绘制它,然后当您在代表中检测到一些拖影时,该如何清理旧的矩形,然后绘制一个新的矩形?嗯,你想拖动矩形或页面?我不知道你的意思是由网页 – radbyx 2012-02-21 09:28:12

0

您最好制作一个自定义控件,该控件绘制图像并将矩形覆盖在顶部。 然后,您可以处理鼠标事件以“移动”矩形。

一些伪代码,让你开始:

class cropcontrol 

onpaint 
    paint image 
    paint rectangle using rect location 

onmousemove 
    if mouse down 
    update rect location