【问题标题】:Winforms: A draggable transparent rectangleWinforms:可拖动的透明矩形
【发布时间】:2012-02-21 17:45:17
【问题描述】:

早上,

此时我正准备睁大眼睛。我正在.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();

            }
        };
    }
}  

谁能给我指出正确的方向或建议去哪里看。

非常感谢

【问题讨论】:

    标签: c# winforms


    【解决方案1】:

    我实际上为屏幕捕获做了一个应用程序,它按照您描述的方式工作,以使其可拖动,我使用鼠标事件。为了使它透明,我简单地用半透明的 png 图像作为背景图像制作了另一个表单控件。

    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;
            }
        }
    

    【讨论】:

    • 这是我正在努力的工作,并即将提出建议。你做了我想说的。 +1
    • 好极了,也许我的眼睛可以一直呆在眼窝里!非常感谢!
    • 那么'rect'你的透明背景图片吗?
    • 是的,抱歉忘记提了
    【解决方案2】:

    看完这篇Painting On Top Of Child Controls你应该可以了

    我自己以前用过ControlPaint.DrawReversibleFrame(_FrameRect, Color.Black, FrameStyle.Dashed);,效果很好:)

    【讨论】:

    • 感谢您的回答,但这是一个不可拖动的橡皮筋矩形。我正在寻找一个可以设置为固定大小的矩形,然后在页面内单击并在页面上拖动。为努力干杯。
    • 如果你先绘制它,然后当你在你的代理中检测到一些拖动时,你首先清理旧的矩形,然后再绘制一个新的矩形怎么办?嗯,您要拖动矩形还是页面?我不知道你说的页面是什么意思
    • 接受的答案提供了一个解决方案,无论如何感谢您的输入! :)
    • 很酷,我很高兴能在短时间内提供任何帮助。 :)
    【解决方案3】:

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

    一些伪代码可以帮助您入门:

    class cropcontrol
    
    onpaint
      paint image
      paint rectangle using rect location
    
    onmousemove
      if mouse down
        update rect location
    

    【讨论】:

      猜你喜欢
      • 2018-03-19
      • 2014-12-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多