2012-01-18 122 views
2

我有自己的控件,我需要通過拖動來調整運行時大小。調整底部和右邊框的大小我使用這個:在運行時調整大小控件

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

所有的工作正常。但我有頂部和左側調整大小的問題:

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

類似的東西。有想法?

+1

你有什麼樣的問題? – 2012-01-18 15:11:32

+0

如果(Height + Top - e.Y <= 1)返回**,我不知道停止調整**的條件。以及如何得到正確**身高**在這部分代碼... – justAuser 2012-01-18 15:25:13

回答

3

幾乎是唯一的方式乾淨允許.NET控件調整大小是使用P/Invoke。這確切的代碼沒有進行測試,但我已經使用這個調整大小的方法很多次,它應該工作:

首先,P /調用外部聲明:

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

最後,重寫OnMouseMove根據它在控件上的位置更改光標。我會將這部分留給你,因爲它與前面的代碼片段幾乎相同。

+0

哦!這是驚人的!很棒!這是我搜索!十分感謝!!! – justAuser 2012-01-19 07:53:09

1

試着改變你的代碼如下:

對於左:

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; 
+0

謝謝,我這樣做的條件: 'if(Width - e.X <= 1)return;' 並且所有的工作都很好,但是當調整速度非常快時我有點閃爍。但它很好。 – justAuser 2012-01-19 06:33:11

2

一個完全脫離的現成的解決方案是將一種形式變成一個控制。表單已經支持調整大小,因此不需要額外的工作。啓動一個新的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); 
    } 
+0

在我的程序中,這種控制會出現很多次。我認爲在我的程序中創建大約30個表單來展示元素並不是一個好主意。我需要這個控件以簡單的形式顯示大小,位置和其他對象。可以在Bitmap上繪製,但是添加大小調整和其他事件需要很長時間。我在想你的建議,對此不是很大的控制嗎? – justAuser 2012-01-19 06:46:01

相關問題