简体   繁体   English

在运行时调整控件的大小

[英]Resizing control at runtime

I have own control and I need to resize runtime by dragging. 我有自己的控件,我需要通过拖动来调整运行时的大小。 To resize bottom and right borders I use this: 要调整底部和右侧边框的大小,请使用以下命令:

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;
  }
}

All works fine. 一切正常。 But I have problems with Top and Left resizing: 但是我在调​​整顶部和左侧大小时遇到​​问题:

// Change Width - left
if (_OnLeft && (!_OnTop && !_OnBottom))
{
  // Problem part - I don't know condition to return
  if (Width + Left - e.X <= 1)
    return;
  Left += e.X - SL.X + SP.X;
  // How to get right width
  Width += Left - e.X;
  return;
}

// Change Height - top
if (_OnTop && (!_OnLeft && !_OnRight))
{
  // Problem part - I don't know condition to return
  if (Height + Top - e.Y <= 1)
    return;
  Top += e.Y - SL.Y + SP.Y;
  // How to get right height 
  Height += Top - e.Y;
  return;
}

Something like that. 这样的事情。 Have ideas? 有想法吗?

Pretty much the only way to cleanly allow .NET control resizing is to use P/Invoke. 完全允许重新调整.NET控件大小的唯一方法是使用P / Invoke。 This exact code is not tested, but I have used this resizing method many times so it should work: 此确切的代码未经测试,但是我已经多次使用此调整大小方法,因此它应该可以工作:

First, the P/Invoke external declarations: 首先,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);
}

Next, call the P/Invoke functions to have the operating system handle the resize: 接下来,调用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.
    }
}

Finally, override OnMouseMove to change the cursor based on where it is on the control. 最后,重写OnMouseMove可以根据光标在控件上的位置来更改光标。 I'll leave that part to you, because it's almost the same code as the previous snippet. 我将把这部分留给您,因为它的代码与上一片段几乎相同。

A completely out-of-box solution is to turn a form into a control. 完全现成的解决方案是将表单转换为控件。 A form already supports resizing so no extra work needs to be done. 表单已经支持调整大小,因此无需执行其他工作。 Start a new Winforms project, add an extra form and try this code to see what it looks like: 启动一个新的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);
    }

Try changing your code to this: 尝试将代码更改为此:

For the left: 对于左边:

int oldLeft = Left;
Left += e.X - SL.X + SP.X;
// How to get right width
// Width += Left - e.X;
Width += oldLeft - Left;

For the top: 对于顶部:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM