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
- 在控件上绘制抓取边框/处理程序
SetStyle
,只需使用中的扩展方法并按以下方式调用:
control.SetStyle(ControlStyles.OptimizedDoubleBuffer |
ControlStyles.AllPaintingInWmPaint |
ControlStyles.ResizeRedraw, true);
我认为使用T4文本模板可以解决您的问题。如果您不熟悉,以下链接可能很有用: 1.
2. 我通常编写一个控制器类,控件可以注册以获得这些服务。看@HansPassant我没有理解你的意思好吧,其中的一部分是我从其他地方复制的,我不需要浪费时间写已经写过的东西,我也不想要求代码都是我的,这只是一个例子,代码要大得多。你可能会感兴趣。
control.SetStyle(ControlStyles.OptimizedDoubleBuffer |
ControlStyles.AllPaintingInWmPaint |
ControlStyles.ResizeRedraw, true);