C# 在运行时调整控件大小

C# 在运行时调整控件大小,c#,winforms,controls,resize,C#,Winforms,Controls,Resize,我有自己的控件,需要通过拖动来调整运行时的大小。要调整底部和右侧边框的大小,我使用以下方法: protected override void OnMouseDown(MouseEventArgs e) { SL = new System.Drawing.Point(Location.X + e.Location.X, Location.Y + e.Location.Y); SP = new System.Drawing.Point(Location.X, Location.Y);

我有自己的控件,需要通过拖动来调整运行时的大小。要调整底部和右侧边框的大小,我使用以下方法:

protected override void OnMouseDown(MouseEventArgs e)
{
  SL = new System.Drawing.Point(Location.X + e.Location.X, Location.Y + e.Location.Y);
  SP = new System.Drawing.Point(Location.X, Location.Y);

  if (e.X <= m)
    _OnLeft = true;

  if (e.X >= Width - m)
    _OnRight = true;

  if (e.Y <= m)
    _OnTop = true;

  if (e.Y >= Height - m)
    _OnBottom = true;
}

protected override void OnMouseMove(MouseEventArgs e)
{
  // Change Width - right
  if (_OnRight && (!_OnTop && !_OnBottom))
  {
    if (e.X <= 1)
      return;
    Width = e.X;
    return;
  }

  // Change Height - bottom
  if (_OnBottom && (!_OnLeft && !_OnRight))
  {
    if (e.Y <= 1)
      return;
    Height = e.Y;
    return;
  }
}
mousedown上的受保护覆盖无效(MouseEventArgs e)
{
SL=新系统.图纸.点(位置.X+e.Location.X,位置.Y+e.Location.Y);
SP=新系统图纸点(位置X,位置Y);
如果(e.X=宽度-m)
_OnRight=true;
如果(e.Y=高度-m)
_OnBottom=true;
}
MouseMove上的受保护覆盖无效(MouseEventArgs e)
{
//更改宽度-右侧
如果(_OnRight&&(!_OnTop&&!_OnBottom))
{

if(e.X完全允许.NET控件调整大小的唯一方法是使用p/Invoke。这段代码没有经过测试,但我已经多次使用过这种调整大小的方法,因此应该可以工作:

首先,p/Invoke外部声明:

private static class UnsafeNativeMethods
{
    [DllImport("user32.dll")]
    public static extern bool ReleaseCapture();
    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
}
接下来,调用p/Invoke函数,让操作系统处理调整大小:

protected override void OnMouseDown(MouseEventArgs e)
{
    int msg = -1; //if (msg == -1) at the end of this, then the mousedown is not a drag.

    if (e.Y < 8)
    {
        msg = 12; //Top
        if (e.X < 25) msg = 13; //Top Left
        if (e.X > Width - 25) msg = 14; //Top Right
    }
    else if (e.X < 8)
    {
        msg = 10; //Left
        if (e.Y < 17) msg = 13;
        if (e.Y > Height - 17) msg = 16;
    }
    else if (e.Y > Height - 9)
    {
        msg = 15; //Bottom
        if (e.X < 25) msg = 16;
        if (e.X > Width - 25) msg = 17;
    }
    else if (e.X > Width - 9)
    {
        msg = 11; //Right
        if (e.Y < 17) msg = 14;
        if (e.Y > Height - 17) msg = 17;
    }

    if (msg != -1)
    {
        UnsafeNativeMethods.ReleaseCapture(); //Release current mouse capture
        UnsafeNativeMethods.SendMessage(Handle, 0xA1, new IntPtr(msg), IntPtr.Zero);
        //Tell the OS that you want to drag the window.
    }
}
mousedown上的受保护覆盖无效(MouseEventArgs e)
{
int msg=-1;//如果(msg==-1)在这个结尾,那么鼠标向下不是拖动。
如果(e.Y<8)
{
msg=12;//顶部
如果(e.X<25)msg=13;//左上角
如果(e.X>Width-25)msg=14;//右上角
}
否则如果(e.X<8)
{
msg=10;//左
如果(e.Y<17)msg=13;
如果(e.Y>高度-17)msg=16;
}
否则,如果(e.Y>高度-9)
{
msg=15;//底部
如果(e.X<25)msg=16;
如果(e.X>宽度-25)msg=17;
}
否则,如果(e.X>宽度-9)
{
msg=11;//对
如果(e.Y<17)msg=14;
如果(e.Y>高度-17)msg=17;
}
如果(消息!=-1)
{
UnsafeNativeMethods.ReleaseCapture();//释放当前鼠标捕获
SendMessage(句柄,0xA1,新的IntPtr(消息),IntPtr.Zero);
//告诉操作系统您要拖动窗口。
}
}

最后,重写OnMouseMove,根据光标在控件上的位置更改光标。我将把这部分留给您,因为它的代码与前面的代码片段几乎相同。

尝试将您的代码更改为:

对于左派:

int oldLeft = Left;
Left += e.X - SL.X + SP.X;
// How to get right width
// Width += Left - e.X;
Width += oldLeft - Left;
对于顶层:

int oldTop = Top;
Top += e.Y - SL.Y + SP.Y;
// How to get right height 
// Height += Top - e.Y;
Height += oldTop - Top;

一个完全现成的解决方案是将窗体转换为控件。窗体已支持调整大小,因此无需执行额外的工作。启动新的Winforms项目,添加一个额外的窗体,然后尝试以下代码以查看其外观:

    public Form1() {
        InitializeComponent();
        var ctl = new Form2();
        ctl.ControlBox = false;
        ctl.Text = "";
        ctl.Location = new Point(10, 10);
        ctl.MinimumSize = new Size(10, 10);
        ctl.TopLevel = false;
        ctl.Visible = true;
        this.Controls.Add(ctl);
        ctl.Size = new Size(100, 100);
    }

你有什么问题?我不知道在if(Height+Top-e.Y)中停止调整大小的条件。谢谢,我是这样做的,条件是:
if(Width-e.X在我的程序中,这样的控件会出现很多次。我认为在我的程序中创建大约30个表单来显示元素不是一个好主意。我需要这个控件来以简单的形式显示其他具有大小、位置和其他内容的对象。可以只在位图上绘制,但添加大小调整和其他事件需要很多时间。我没有这样做想想你的建议,这不是很大的控制吗?
    public Form1() {
        InitializeComponent();
        var ctl = new Form2();
        ctl.ControlBox = false;
        ctl.Text = "";
        ctl.Location = new Point(10, 10);
        ctl.MinimumSize = new Size(10, 10);
        ctl.TopLevel = false;
        ctl.Visible = true;
        this.Controls.Add(ctl);
        ctl.Size = new Size(100, 100);
    }