Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 向winforms中的多个控件添加相同的扩展_C#_Winforms - Fatal编程技术网

C# 向winforms中的多个控件添加相同的扩展

C# 向winforms中的多个控件添加相同的扩展,c#,winforms,C#,Winforms,我想添加一些扩展,如移动,调整大小,。。。要图片盒,标签,面板,如下所示: public class LiveControl: PictureBox { private Point cur = new Point(0, 0); public LiveControl() { ResizeRedraw = true; MouseDown += (s, e) => { cur = new Point(e.X, e.Y); };

我想添加一些扩展,如移动,调整大小,。。。要
图片盒
标签
面板
,如下所示:

public class LiveControl: PictureBox
{
    private Point cur = new Point(0, 0);
    public LiveControl()
    {
        ResizeRedraw = true;
        MouseDown += (s, e) => { cur = new Point(e.X, e.Y); };
        MouseMove += (s, e) => {
            if (e.Button == MouseButtons.Left)
            {
                Control x = (Control)s;
                x.SuspendLayout();
                x.Location = new Point(x.Left + e.X - cur.X, x.Top + e.Y - cur.Y);
                x.ResumeLayout();
            }
        };
    }
    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);
        var rc = new Rectangle(this.ClientSize.Width - grab, this.ClientSize.Height - grab, grab, grab);
        ControlPaint.DrawSizeGrip(e.Graphics, this.BackColor, rc);
    }
    protected override void WndProc(ref Message m)
    {
        base.WndProc(ref m);
        if (m.Msg == 0x84)
        {  
            var pos = this.PointToClient(new Point(m.LParam.ToInt32() & 0xffff, m.LParam.ToInt32() >> 16));
            if (pos.X >= this.ClientSize.Width - grab && pos.Y >= this.ClientSize.Height - grab)
                m.Result = new IntPtr(17);  
        }
    }
    private const int grab = 16;
}

我是否应该像类一样编写它并为所有类继承它,还是应该像为
PictureBox
编写的那样编写3个单独的类?

您可以将逻辑封装在从类派生的帮助器类中。通过这种方式,您可以在不为要移动/调整大小的每个控件创建派生类的情况下完成此工作

可以将要扩展的控件传递给helper类的构造函数,并将控件句柄分配给本机窗口。然后重写本机窗口的
WndProc
,将处理控件的消息

另外,通过保留对在构造函数中传递的控件的引用并分配事件处理程序,也可以处理控件的事件

创建此类本机窗口帮助器类后,用法如下:

var h1 = new LiveControlHelper(this.pictureBox1);
var h2 = new LiveControlHelper(this.button1);
或者,可以对循环中容器的所有控件使用帮助器

示例

在下面的示例中,我重构了您发布的代码。这样,您就可以将代码用于所有控件,而无需继承

using System;
using System.Drawing;
using System.Windows.Forms;
注意

1-要将控件恢复到正常状态(不可调整大小,不可移动),最好使用方法而不使用lambda分配事件处理程序。您需要重新启动事件处理程序以将控件恢复到其正常状态。为此,还需要调用helper类的
DestroyHanlde
方法

2-我刚刚对发布的代码进行了重构,使其可用于控件,而无需实现所有控件的派生版本。但您可以通过以下方式增强代码:

  • 通过将
    m.Result
    设置为合适的值,可以使用控件的曲面、边和角移动控件并调整其大小

  • 在控件上绘制抓取边框/处理程序

3-如果需要调用控件上的
SetStyle
,只需使用中的扩展方法并按以下方式调用:

control.SetStyle(ControlStyles.OptimizedDoubleBuffer |
    ControlStyles.AllPaintingInWmPaint |
    ControlStyles.ResizeRedraw, true);

我认为使用T4文本模板可以解决您的问题。如果您不熟悉,以下链接可能很有用: 1.
2.

我通常编写一个控制器类,控件可以注册以获得这些服务。看@HansPassant我没有理解你的意思好吧,其中的一部分是我从其他地方复制的,我不需要浪费时间写已经写过的东西,我也不想要求代码都是我的,这只是一个例子,代码要大得多。你可能会感兴趣。
control.SetStyle(ControlStyles.OptimizedDoubleBuffer |
    ControlStyles.AllPaintingInWmPaint |
    ControlStyles.ResizeRedraw, true);