2013-06-23 13 views

Odpowiedz

3

tutaj jest artykuł

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

które powinny pomóc, gdyż w VB tutaj tłumaczeniem C#

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

} 

I RE-SIZE FUNKCJI

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

Cóż, wolałbym wdrożyć własne rozwiązanie, ale wygląd kodu wydaje się być poza moimi możliwościami implementacji takiej rzeczy. –

+0

To nie jest tak proste, jak mogłoby się wydawać, ponieważ od czasu, gdy robisz to w czasie wykonywania, musisz zaktualizować kontrolkę w czasie wykonywania i śledzić punkty Myślę, że to rozwiązanie jest proste –

+0

Naprawdę wolałbym zaimplementować własne rozwiązanie. łatwiej zrobić w XAML? –

25

To jest dość łatwe do zrobienia, każde okno w Windows ma wrodzoną zdolność do bycia resi zable. Jest wyłączony dla PictureBox, można go włączyć, nasłuchując na WM_NCHITTEST message. Po prostu powiesz Windowsowi, że kursor znajduje się w rogu okna, dostajesz wszystko inne za darmo. Będziesz także chciał narysować uchwyt do chwytania, aby użytkownik wiedział, że przeciągnięcie rogu spowoduje zmianę rozmiaru okna.

Dodaj nową klasę do swojego projektu i wklej poniższy kod. Buduj i buduj. Dostaniesz nową kontrolę nad zestawem narzędzi, upuść ją na formularzu. Ustaw właściwość Obraz i możesz ją wypróbować.

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

Innym bardzo tani sposób, aby uzyskać zmianę rozmiaru za darmo jest dając regulator granicę zmienny rozmiar. Który działa na wszystkich narożnikach i krawędziach. Wklej ten kod do klasy (nie trzeba już WndProc):

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

Ok, więc teraz jestem w stanie zmienić rozmiar kontrolki w czasie wykonywania. Uchwyt zmiany rozmiaru pojawia się jednak tylko w prawym dolnym rogu kontrolki. Czy jest jakikolwiek sposób, że mogę zmienić rozmiar kontrolki z dowolnego miejsca, tak jak to robimy w visual studio podczas umieszczania kontrolek. –

+1

Bardzo lubię tę odpowiedź. W odniesieniu do ograniczenia wspomnianego przez @WinCoder, możesz zmienić rozmiar z dowolnej strony kontroli za pomocą drugiego rozwiązania, jeśli wartość '0x840000' zostanie zastąpiona przez' 0x00040000' w linii 'cp.Style | = 0x840000;'. Ustawia styl na WS_SIZEBOX. [Odniesienie tutaj] (https://msdn.microsoft.com/en-us/library/windows/desktop/ms632600 (v = vs.85) .aspx) – u8it

2

z wykorzystaniem klasy ControlMoverOrResizer w this article można zrobić kontrole ruchome i skalowalne w czasie wykonywania tylko z linii kodu! :) przykład:

ControlMoverOrResizer.Init (button1);

, a teraz przycisk 1 to ruchomy i dostosowywany rozmiar!

1

utworzenia nowej aplikacji C# winform i wklej:

Nie zapomnij podziękować gdy ci pomóc ...

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

Pozdrawiam, Kix46

Powiązane problemy