2013-06-23 35 views
11

Giả sử tôi có một hộp ảnh.Làm cách nào để người dùng có thể thay đổi kích thước điều khiển khi chạy trong winforms

Bây giờ những gì tôi muốn là người dùng sẽ có thể thay đổi kích thước của pictureBox theo ý muốn. Tuy nhiên tôi không có ý tưởng về làm thế nào để thậm chí bắt đầu vào điều này. Tôi đã tìm kiếm trên internet tuy nhiên thông tin là khan hiếm.

Có ai ít nhất có thể hướng dẫn tôi về nơi bắt đầu không?

Trả lời

3

đây là một bài viết

http://www.codeproject.com/Articles/20716/Allow-the-User-to-Resize-Controls-at-Runtime

rằng sẽ giúp bạn vì nó trong vb đây một C# dịch

using System; 
using System.Collections; 
using System.Collections.Generic; 
using System.Data; 
using System.Diagnostics; 
public class Form1 
{ 


    ResizeableControl rc; 

    private void Form1_Load(System.Object sender, System.EventArgs e) 
    { 
     rc = new ResizeableControl(pbDemo); 

    } 
    public Form1() 
    { 
     Load += Form1_Load; 
    } 

} 

VÀ RE-SIZE CHỨC NĂNG

using System; 
using System.Collections; 
using System.Collections.Generic; 
using System.Data; 
using System.Diagnostics; 
public class ResizeableControl 
{ 

    private Control withEventsField_mControl; 
    private Control mControl { 
     get { return withEventsField_mControl; } 
     set { 
      if (withEventsField_mControl != null) { 
       withEventsField_mControl.MouseDown -= mControl_MouseDown; 
       withEventsField_mControl.MouseUp -= mControl_MouseUp; 
       withEventsField_mControl.MouseMove -= mControl_MouseMove; 
       withEventsField_mControl.MouseLeave -= mControl_MouseLeave; 
      } 
      withEventsField_mControl = value; 
      if (withEventsField_mControl != null) { 
       withEventsField_mControl.MouseDown += mControl_MouseDown; 
       withEventsField_mControl.MouseUp += mControl_MouseUp; 
       withEventsField_mControl.MouseMove += mControl_MouseMove; 
       withEventsField_mControl.MouseLeave += mControl_MouseLeave; 
      } 
     } 
    } 
    private bool mMouseDown = false; 
    private EdgeEnum mEdge = EdgeEnum.None; 
    private int mWidth = 4; 

    private bool mOutlineDrawn = false; 
    private enum EdgeEnum 
    { 
     None, 
     Right, 
     Left, 
     Top, 
     Bottom, 
     TopLeft 
    } 

    public ResizeableControl(Control Control) 
    { 
     mControl = Control; 
    } 


    private void mControl_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e) 
    { 
     if (e.Button == System.Windows.Forms.MouseButtons.Left) { 
      mMouseDown = true; 
     } 
    } 


    private void mControl_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e) 
    { 
     mMouseDown = false; 
    } 


    private void mControl_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e) 
    { 
     Control c = (Control)sender; 
     Graphics g = c.CreateGraphics; 
     switch (mEdge) { 
      case EdgeEnum.TopLeft: 
       g.FillRectangle(Brushes.Fuchsia, 0, 0, mWidth * 4, mWidth * 4); 
       mOutlineDrawn = true; 
       break; 
      case EdgeEnum.Left: 
       g.FillRectangle(Brushes.Fuchsia, 0, 0, mWidth, c.Height); 
       mOutlineDrawn = true; 
       break; 
      case EdgeEnum.Right: 
       g.FillRectangle(Brushes.Fuchsia, c.Width - mWidth, 0, c.Width, c.Height); 
       mOutlineDrawn = true; 
       break; 
      case EdgeEnum.Top: 
       g.FillRectangle(Brushes.Fuchsia, 0, 0, c.Width, mWidth); 
       mOutlineDrawn = true; 
       break; 
      case EdgeEnum.Bottom: 
       g.FillRectangle(Brushes.Fuchsia, 0, c.Height - mWidth, c.Width, mWidth); 
       mOutlineDrawn = true; 
       break; 
      case EdgeEnum.None: 
       if (mOutlineDrawn) { 
        c.Refresh(); 
        mOutlineDrawn = false; 
       } 
       break; 
     } 

     if (mMouseDown & mEdge != EdgeEnum.None) { 
      c.SuspendLayout(); 
      switch (mEdge) { 
       case EdgeEnum.TopLeft: 
        c.SetBounds(c.Left + e.X, c.Top + e.Y, c.Width, c.Height); 
        break; 
       case EdgeEnum.Left: 
        c.SetBounds(c.Left + e.X, c.Top, c.Width - e.X, c.Height); 
        break; 
       case EdgeEnum.Right: 
        c.SetBounds(c.Left, c.Top, c.Width - (c.Width - e.X), c.Height); 
        break; 
       case EdgeEnum.Top: 
        c.SetBounds(c.Left, c.Top + e.Y, c.Width, c.Height - e.Y); 
        break; 
       case EdgeEnum.Bottom: 
        c.SetBounds(c.Left, c.Top, c.Width, c.Height - (c.Height - e.Y)); 
        break; 
      } 
      c.ResumeLayout(); 
     } else { 
      switch (true) { 
       case e.X <= (mWidth * 4) & e.Y <= (mWidth * 4): 
        //top left corner 
        c.Cursor = Cursors.SizeAll; 
        mEdge = EdgeEnum.TopLeft; 
        break; 
       case e.X <= mWidth: 
        //left edge 
        c.Cursor = Cursors.VSplit; 
        mEdge = EdgeEnum.Left; 
        break; 
       case e.X > c.Width - (mWidth + 1): 
        //right edge 
        c.Cursor = Cursors.VSplit; 
        mEdge = EdgeEnum.Right; 
        break; 
       case e.Y <= mWidth: 
        //top edge 
        c.Cursor = Cursors.HSplit; 
        mEdge = EdgeEnum.Top; 
        break; 
       case e.Y > c.Height - (mWidth + 1): 
        //bottom edge 
        c.Cursor = Cursors.HSplit; 
        mEdge = EdgeEnum.Bottom; 
        break; 
       default: 
        //no edge 
        c.Cursor = Cursors.Default; 
        mEdge = EdgeEnum.None; 
        break; 
      } 
     } 
    } 


    private void mControl_MouseLeave(object sender, System.EventArgs e) 
    { 
     Control c = (Control)sender; 
     mEdge = EdgeEnum.None; 
     c.Refresh(); 
    } 

} 
+0

Vâng tôi sẽ có ưa thích thực hiện giải pháp của riêng tôi nhưng bởi vẻ của mã nó có vẻ vượt quá khả năng của tôi để thực hiện một điều như vậy. –

+0

nó không đơn giản vì nó có thể âm thanh bởi vì kể từ khi bạn làm nó tại thời gian chạy, bạn phải cập nhật điều khiển tại thời gian chạy và theo dõi các điểm tôi nghĩ rằng giải pháp này đơn giản là –

+0

tôi thực sự muốn thực hiện giải pháp của riêng mình dễ dàng hơn trong XAML? –

25

Đây là khá dễ làm, mỗi cửa sổ trong Windows có khả năng bẩm sinh để được resi zable. Nó chỉ được tắt cho một PictureBox, bạn có thể bật nó trở lại bằng cách lắng nghe cho WM_NCHITTEST message. Bạn chỉ cần nói với Windows rằng con trỏ nằm ở góc của một cửa sổ, bạn sẽ nhận được mọi thứ miễn phí khác. Bạn cũng sẽ muốn vẽ một tay cầm lấy để nó rõ ràng cho người dùng mà kéo góc sẽ thay đổi kích thước hộp.

Thêm lớp mới vào dự án của bạn và dán mã được hiển thị bên dưới. Xây dựng + Xây dựng. Bạn sẽ nhận được một điều khiển mới trên đầu trang của hộp công cụ, thả nó trên một biểu mẫu. Đặt thuộc tính Hình ảnh và bạn đã đặt để thử nó.

using System; 
using System.Drawing; 
using System.Windows.Forms; 

class SizeablePictureBox : PictureBox { 
    public SizeablePictureBox() { 
     this.ResizeRedraw = true; 
    } 
    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) { // Trap WM_NCHITTEST 
      var pos = this.PointToClient(new Point(m.LParam.ToInt32())); 
      if (pos.X >= this.ClientSize.Width - grab && pos.Y >= this.ClientSize.Height - grab) 
       m.Result = new IntPtr(17); // HT_BOTTOMRIGHT 
     } 
    } 
    private const int grab = 16; 
} 

Một rất cách rẻ tiền để có được những thay đổi kích thước cho miễn phí bằng cách cho sự kiểm soát đường biên giới thay đổi kích thước. Hoạt động trên tất cả các góc và cạnh. Dán mã này vào lớp (bạn không cần WndProc nữa):

protected override CreateParams CreateParams { 
    get { 
     var cp = base.CreateParams; 
     cp.Style |= 0x840000; // Turn on WS_BORDER + WS_THICKFRAME 
     return cp; 
    } 
} 
+0

Ok vì vậy bây giờ tôi có thể thay đổi kích thước điều khiển trong thời gian chạy. Tuy nhiên, điều khiển thay đổi kích thước chỉ xuất hiện ở góc dưới cùng bên phải của điều khiển. Có cách nào mà tôi có thể thay đổi kích thước điều khiển từ bất cứ nơi nào tôi muốn loại giống như chúng tôi làm trong studio trực quan khi đặt điều khiển. –

+1

Tôi thích câu trả lời này rất nhiều. Đối với giới hạn được đề cập bởi @WinCoder, bạn có thể thay đổi kích thước từ bất kỳ phía nào của điều khiển bằng giải pháp thứ hai nếu giá trị '0x840000' được thay thế bằng' 0x00040000' trong dòng 'cp.Style | = 0x840000;'. Điều này đặt kiểu cho WS_SIZEBOX. [Tham khảo tại đây] (https://msdn.microsoft.com/en-us/library/windows/desktop/ms632600 (v = vs.85) .aspx) – u8it

2

với việc sử dụng lớp ControlMoverOrResizer trong this article bạn có thể làm điều khiển di chuyển và thay đổi kích thước trong thời gian chạy chỉ với một dòng mã! :) ví dụ:

ControlMoverOrResizer.Init (button1);

và bây giờ button1 là một điều khiển có thể di chuyển và thay đổi kích thước!

1

Tạo một ứng dụng C# Winform mới và dán này:

Đừng quên nói lời cảm ơn khi nó giúp bạn ...

http://www.codeproject.com/script/Articles/ArticleVersion.aspx?aid=743923&av=1095793&msg=4778687

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 

namespace WindowsFormsApplication1 
    { 
public partial class MyForm : Form 
    { 
    //Public Declaration: 
    double rW = 0; 
    double rH = 0; 

    int fH = 0; 
    int fW = 0; 


    // @ Form Initialization 
    public MyForm() 
    { 
     InitializeComponent(); 
     this.Resize += MyForm_Resize; // handles resize routine 
     this.tabControl1.Dock = DockStyle.None; 

    } 


    private void MyForm_Resize(object sender, EventArgs e) 
    { 
     rResize(this,true); //Call the routine 

    } 

    private void rResize(Control t, bool hasTabs) // Routine to Auto resize the control 
    { 

     // this will return to normal default size when 1 of the conditions is met 

     string[] s = null; 

     if (this.Width < fW || this.Height < fH) 
     { 

      this.Width = (int)fW; 
      this.Height = (int)fH; 

      return; 
     } 

     foreach (Control c in t.Controls) 
     { 
      // Option 1: 
      double rRW = (t.Width > rW ? t.Width/(rW) : rW/t.Width); 
      double rRH = (t.Height > rH ? t.Height/(rH) : rH/t.Height); 

      // Option 2: 
      // double rRW = t.Width/rW; 
      // double rRH = t.Height/rH; 

      s = c.Tag.ToString().Split('/'); 
      if (c.Name == s[0].ToString()) 
      { 
       //Use integer casting 
       c.Width = (int)(Convert.ToInt32(s[3]) * rRW); 
       c.Height = (int)(Convert.ToInt32(s[4]) * rRH); 
       c.Left = (int)(Convert.ToInt32(s[1]) * rRW); 
       c.Top = (int)(Convert.ToInt32(s[2]) * rRH); 
      } 
      if (hasTabs) 
      { 
       if (c.GetType() == typeof(TabControl)) 
       { 

        foreach (Control f in c.Controls) 
        { 
         foreach (Control j in f.Controls) //tabpage 
         { 
          s = j.Tag.ToString().Split('/'); 

          if (j.Name == s[0].ToString()) 
          { 

           j.Width = (int)(Convert.ToInt32(s[3]) * rRW); 
           j.Height = (int)(Convert.ToInt32(s[4]) * rRH); 
           j.Left = (int)(Convert.ToInt32(s[1]) * rRW); 
           j.Top = (int)(Convert.ToInt32(s[2]) * rRH); 
          } 
         } 
        } 
       } 
      } 

     } 
    } 

    // @ Form Load Event 
    private void MyForm_Load(object sender, EventArgs e) 
    { 


     // Put values in the variables 

     rW = this.Width; 
     rH = this.Height; 

     fW = this.Width; 
     fH = this.Height; 


     // Loop through the controls inside the form i.e. Tabcontrol Container 
     foreach (Control c in this.Controls) 
     { 
      c.Tag = c.Name + "/" + c.Left + "/" + c.Top + "/" + c.Width + "/" + c.Height; 

      // c.Anchor = (AnchorStyles.Right | AnchorStyles.Left); 

      if (c.GetType() == typeof(TabControl)) 
      { 

       foreach (Control f in c.Controls) 
       { 

        foreach (Control j in f.Controls) //tabpage 
        { 
         j.Tag = j.Name + "/" + j.Left + "/" + j.Top + "/" + j.Width + "/" + j.Height; 
        } 
       } 
      } 
     } 
    } 
} 
} 

Kính trọng, Kix46

Các vấn đề liên quan