【问题标题】:Highlight the Rectangular Area while Dragging it拖动时突出显示矩形区域
【发布时间】:2012-04-11 01:56:53
【问题描述】:

我正在创建一个图像查看器之类的应用程序。我在 Windows 上并使用 .Net

在我的应用程序中,我试图在拖动时突出显示特定区域。 我创建了一个矩形。

Rectangle areaRect = new Rectangle(100,100, 300, 300);
Point ptOld = new Point(0, 0);
Pen rectPen = new Pen(Brushes.White, 3);

protected override void OnPaint(PaintEventArgs e)
{
  Graphics dcPaint = e.Graphics;
  dcPaint.DrawRectangle(rectPen, areaRect);
}

现在我随着鼠标的移动拖动这个矩形区域。

protected override void OnMouseMove(MouseEventArgs e)
{
 Point ptNew = new Point(e.X, e.Y);
 int dx = ptNew.X - ptOld.X;
 int dy = ptNew.Y - ptOld.Y;
 areaRect.Offset(dx, dy);
 MoveRect(ptNew);
 ptOld = ptNew;
}

我正在尝试用鼠标移动这个矩形

void MoveRect(Point point)
{
 Graphics grfxClient = CreateGraphics();
 Rectangle tempRectangle = new Rectangle(areaRect.Left, areaRect.Top, areaRect.Width,   areaRect.Height);
 grfxClient.DrawRectangle(rectPen, tempRectangle);
 this.Invalidate();
 grfxClient.Dispose();
}

到目前为止,我的代码运行良好。 现在我想将反向拖动区域(拖动区域之外的区域)变暗,我的意思是这个矩形内的区域应该在拖动时突出显示。

知道如何继续。

谢谢。

-潘卡杰

【问题讨论】:

    标签: c# gdi


    【解决方案1】:

    我想你可以通过创建一个覆盖矩形外部的Region 对象并用半透明的SolidBrush 填充它以使其看起来变暗来实现。

    您也不必在OnMouseMove 事件中创建图形并进行绘制,而只需移动矩形并使您正在绘制的控件的表面无效。

    我使用的代码或多或少是这样的:

    Rectangle areaRect = new Rectangle(100,100, 300, 300);
    Point ptOld = new Point(0, 0);
    Pen rectPen = new Pen(Brushes.White, 3);
    
    //A new field with a semi-transparent brush to paint the outside of the rectangle
    Brush dimmingBrush = new SolidBrush(Color.FromArgb(128, 0, 0, 0));
    
    protected override void OnPaint(PaintEventArgs e)
    {
        Region outsideRegion = new System.Drawing.Region(e.ClipRectangle);
        outsideRegion.Exclude(areaRect);
        Graphics dcPaint = e.Graphics;
        dcPaint.FillRegion(dimmingBrush, outsideRegion);
        dcPaint.DrawRectangle(rectPen, areaRect);
    }
    
    protected override void OnMouseMove(MouseEventArgs e)
    {
        Point ptNew = new Point(e.X, e.Y);
        int dx = ptNew.X - ptOld.X;
        int dy = ptNew.Y - ptOld.Y;
        areaRect.Offset(dx, dy);
        ptOld = ptNew;
        this.Invalidate();
    }
    

    不需要MoveRect这个方法。

    它现在似乎可以按您的意愿工作了。

    建议

    我也有一些建议。您不必使用它们,也许它们会对您有所帮助。

    你还没有写出你用什么样的控件来绘制(或者覆盖Form方法并直接在上面绘制),但是我建议你使用PictureBox控件,创建一个自定义控件,从它并覆盖它的事件。这应该使绘画过程顺利并防止闪烁。这样做:

    • 通过选择 AddUser Control... 创建一个新的用户控件,并命名一个新控件,即MyPictureBox
    • 更改控件的父类,因此它现在应该包含以下行:

      public partial class MyPictureBox : PictureBox
      
    • 打开文件MyPictureBox.Designer.cs并注释掉这些行:

      //this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
      //this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
      
    • 复制我在此答案中发布的代码并添加行 base.OnPaint(e);OnPaint 方法的开头

    • 编译项目

    • 现在您应该可以打开主窗体的设计器,从工具箱中拖动 MyPictureBox 控件并使用它,无需额外代码

    您还可以考虑更改突出显示区域的行为,使鼠标光标位于其中心。我想这对用户来说会更直观。

    如果您对代码有任何问题,只需将其写在 cmets 中,我会尽力提供帮助 :)。

    【讨论】:

    • 感谢 Lucas,它的工作原理正是我所需要的。是的,我在 Custom PictureBox 类的顶部创建了这个 Rectangle,我不仅移动了这个 Rect,还可以完美地调整它的大小(保持其中一个角)再次感谢。
    • 我很高兴它有帮助:)。如果您能将我的答案标记为正确,我将不胜感激:)。
    猜你喜欢
    • 2023-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-10
    相关资源
    最近更新 更多