【问题标题】:Strange effect when resizing Control调整控件大小时的奇怪效果
【发布时间】:2015-05-21 07:09:39
【问题描述】:

我创建了两个自定义控件。一个矩形和一个椭圆。我可以通过鼠标拖动来移动它们,但我也想调整它们的大小。矩形调整大小工作正常,但椭圆调整大小会产生奇怪的效果。当我在调整大小后单击椭圆并再次拖动它时,椭圆看起来又正常了。此处带有 gif 的链接显示了我所说的“奇怪”效果 http://gyazo.com/319adb7347ed20fe28b6b93ced8744eb 的意思。如何修复这个效果?椭圆的角落也有一些空白,因为它是绘制成矩形的,也许有办法解决这个问题?

Control.cs

class Ellipse : Control
{
    Point mDown { get; set; }

    public Ellipse()
    {
        MouseDown += shape_MouseDown;
        MouseMove += shape_MouseMove;
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);

        // Draw a black ellipse in the rectangle represented by the control.
        e.Graphics.FillEllipse(Brushes.Black, 0, 0, Width, Height);

        //Set transparent background
        SetStyle(ControlStyles.SupportsTransparentBackColor | ControlStyles.DoubleBuffer, true);
        this.BackColor = Color.Transparent;
    }  

    public void shape_MouseDown(object sender, MouseEventArgs e)
    {
        mDown = e.Location;
    }

    public void shape_MouseMove(object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Left)
        {
            Location = new Point(e.X + Left - mDown.X, e.Y + Top - mDown.Y);
        }
    }

    /* Allow resizing at the bottom right corner */
    protected override void WndProc(ref Message m)
    {
        const int wmNcHitTest = 0x84;
        const int htBottomLeft = 16;
        const int htBottomRight = 17;
        if (m.Msg == wmNcHitTest)
        {
            int x = (int)(m.LParam.ToInt64() & 0xFFFF);
            int y = (int)((m.LParam.ToInt64() & 0xFFFF0000) >> 16);
            Point pt = PointToClient(new Point(x, y));
            Size clientSize = ClientSize;
            if (pt.X >= clientSize.Width - 16 && pt.Y >= clientSize.Height - 16 && clientSize.Height >= 16)
            {
                m.Result = (IntPtr)(IsMirrored ? htBottomLeft : htBottomRight);
                return;
            }
        }
        base.WndProc(ref m);
    }
  } 
}

Form1.cs

通过这种方式,我创建了Ellipse,此代码来自panel_MouseUp (object sender, MouseEventArgs e) 方法。

case Item.Ellipse:
var el = new Ellipse();
panel.Controls.Add(el);
el.Location = new Point(x, y);
el.Width = (xe - x);
el.Height = (ye - y);
break;

【问题讨论】:

    标签: c# winforms controls


    【解决方案1】:

    您需要告诉控件在调整大小时完全重新绘制自身。将其 ResizeRedraw 属性设置为 true。您还需要小心您在 Paint 事件处理程序中所做的事情,它不应该有全局状态副作用。正如所写,当我尝试时,您的控件立即使设计器崩溃。

    从 OnPaint 中删除最后 2 行,并使您的构造函数如下所示:

    public Ellipse() {
        MouseDown += shape_MouseDown;
        MouseMove += shape_MouseMove;
        SetStyle(ControlStyles.SupportsTransparentBackColor, true);
        this.BackColor = Color.Transparent;
        this.DoubleBuffered = true;
        this.ResizeRedraw = true;
    }
    

    通过重写 OnMouseDown/Move() 而不是使用事件来进一步改进这一点。并查看 ControlPaint.DrawGrabHandle() 以使调整大小更直观。

    【讨论】:

      猜你喜欢
      • 2019-01-05
      • 2017-10-30
      • 2011-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-17
      相关资源
      最近更新 更多