2013-05-10 30 views
2

我對這個社區很新穎,而且我有這個以編程方式添加控件的應用程序。 我想集中所有添加的控件,比如選擇它們並按下Visual Studio中心。不,我不想把每個人放在一邊。 下面是我用來獲取所有控件的代碼:預先如何以編程方式在c中集中一堆控件#

private void GetAllControl(Control c, List<Control> list) 
    { 
     //gets all controls and saves them to a list 
     foreach (Control control in c.Controls) 
     { 
      list.Add(control); 
     } 
    } 

    //And then call it like this 

     List<Control> list = new List<Control>(); 
     GetAllControl(PNL_custom, list); 
     foreach (Play_panel m in list) 
     { 
      //And here I want to insert that center code 
     } 

謝謝,

VBTheory

+0

這是一個WinForms桌面應用程序? – DOK 2013-05-10 12:19:07

+1

當然它是:) – vbtheory 2013-05-10 12:21:39

+1

它可以幫助你吸引人們的注意力,如果你提供一個標籤,例如WinForms或WPF或ASP.Net,他們可以提供幫助。 – DOK 2013-05-10 12:22:59

回答

1

下面是如何中心的控制作爲集團。除了我們計算組的質量中心移動到成爲父控制中心的距離之外,它幾乎與以前相同。然後我們遍歷所有的控件,並通過這些來抵消它們的位置。該中心所有這些,同時保持相對於彼此的位置:

public partial class Form1 : Form 
{ 
    public Form1() 
    { 
     InitializeComponent(); 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     List<Control> list = new List<Control>(); 
     GetAllControl(PNL_custom, list); 
     CenterControlsAsGroup(list, Direction.Both); // center group in the center of the parent 
    } 

    public enum Direction 
    { 
     Vertical, 
     Horizontal, 
     Both 
    } 

    private void CenterControlsAsGroup(List<Control> controls, Direction direction) 
    { 
     if (controls.Count > 1) 
     { 
      int xSum = 0; 
      int ySum = 0; 
      Point center; 
      foreach (Control ctl in controls) 
      { 
       center = new Point(ctl.Location.X + ctl.Width/2, ctl.Location.Y + ctl.Height/2); 
       xSum = xSum + center.X; 
       ySum = ySum + center.Y; 
      } 
      Point average = new Point(xSum/controls.Count, ySum/controls.Count); 

      center = new Point(controls[0].Parent.Width/2, controls[0].Parent.Height/2); 
      int xOffset = center.X - average.X; 
      int yOffset = center.Y - average.Y; 

      foreach (Control ctl in controls) 
      { 
       switch (direction) 
       { 
        case Direction.Vertical: 
         ctl.Location = new Point(ctl.Location.X + xOffset, ctl.Location.Y); 
         break; 

        case Direction.Horizontal: 
         ctl.Location = new Point(ctl.Location.X, ctl.Location.Y + yOffset); 
         break; 

        case Direction.Both: 
         ctl.Location = new Point(ctl.Location.X + xOffset, ctl.Location.Y + yOffset); 
         break; 
       } 
      } 
     } 
    } 

    private void GetAllControl(Control c, List<Control> list) 
    { 
     //gets all controls and saves them to a list 
     foreach (Control control in c.Controls) 
     { 
      list.Add(control); 
     } 
    } 

} 
+0

OMG我永遠不會感謝你足夠。謝謝你如此驚人的兄弟 – vbtheory 2013-05-10 22:46:19

+0

很高興爲你工作。隨時upvote和/或點擊複選標記,以便其他人知道問題已解決... – 2013-05-10 22:56:43

+0

我試圖upvote,但它說我需要更多的特權:( – vbtheory 2013-05-10 23:37:23

1

獲取控制的容器的寬度和高度(其是另一種控制或形式)。控件的座標是相對於其容器左上角(即(0,0))的距離(以像素爲單位)。所以你所要做的就是設置一個控件的x座標爲(form width - control width)/2。身高也一樣。

+0

您可以更具體地指出 – vbtheory 2013-05-10 12:22:11

+0

容器的左上角是座標系中的(0,0)點。座標值向右和向下增長。您可能需要查看[位置](http://msdn.microsoft.com/zh-cn/library/system.windows.forms.control.location.aspx)屬性。所以你可以像'm.Location.X =(m.Parent.Width - m.Width)/ 2'這樣做來水平居中。用'Y'代替'X'和'Height'代表你也垂直居中的'Width'。 – Renan 2013-05-10 12:26:09

0

所有控件將被添加到一個容器(最有可能的形式),但他們可以很容易地在一組框等

要調整它們的容器內中心,你需要做一些數學和位置他們自己:)

在您可以將控件居中在容器中之前,您需要找到容器的中點。這將是容器的寬度/ 2:容器的高度/ 2。

我將使用一個名爲cmdButton1的控件來突出顯示 - 您將要遍歷控件列表,並依次對所有控件執行此操作。

cmdButton1.Location.X = midParentX; 
cmdButton1.Location.Y = midParentY; 

然而,你的控制(cmdButton在我的例子),在(0,0)被錨定是控制的左上角:

int midParentX = cmdButton1.Parent.width/2; 
int midParentX = cmdButton1.Parent.height/2; 

然後你就可以在這個中間位置的控制,所以我們需要一半自己的寬度和高度,將其移回最多

cmdButton1.Location.X -= (cmdButton1.width/2); 
cmdButton1.Location.Y -= (cmdButton1.height/2); 

更相關:

foreach (Play_panel m in list) 
{ 
    int pX = m.Parent.width; 
    int pY = m.Parent.height; 

    m.Location.X = (pX/2) - (m.width/2); 
    m.Location.Y = (pY/2) - (m.height/2); 
} 
2

「不,我不想把每個人放在一邊。」

所以要 「對齊」 控件列表...如:

格式 - >對齊 - >中心

格式 - >對齊 - > Middles

如果是,則計算每個控件的中心並將X,Y座標相加,以便計算「平均」點(質心)。現在,您可以遍歷控件並將其用作對齊X或Y值,具體取決於您希望的方向。簡單地減去寬度或高度的一半並保留另一個值。

喜歡的東西:

public partial class Form1 : Form 
{ 
    public Form1() 
    { 
     InitializeComponent(); 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     List<Control> list = new List<Control>(); 
     GetAllControl(PNL_custom, list); 
     CenterControls(list, Direction.Vertical); 
    } 

    public enum Direction 
    { 
     Vertical, 
     Horizontal 
    } 

    private void CenterControls(List<Control> controls, Direction direction) 
    { 
     if (controls.Count > 1) 
     { 
      int xSum = 0; 
      int ySum = 0; 
      Point center; 
      foreach (Control ctl in controls) 
      { 
       center = new Point(ctl.Location.X + ctl.Width/2, ctl.Location.Y + ctl.Height/2); 
       xSum = xSum + center.X; 
       ySum = ySum + center.Y; 
      } 
      Point average = new Point(xSum/controls.Count, ySum/controls.Count); 
      foreach (Control ctl in controls) 
      { 
       switch (direction) 
       { 
        case Direction.Vertical: 
         ctl.Location = new Point(average.X - ctl.Width/2, ctl.Location.Y); 
         break; 

        case Direction.Horizontal: 
         ctl.Location = new Point(ctl.Location.X, average.Y - ctl.Height/2); 
         break; 
       } 
      } 
     } 
    } 

    private void GetAllControl(Control c, List<Control> list) 
    { 
     //gets all controls and saves them to a list 
     foreach (Control control in c.Controls) 
     { 
      list.Add(control); 
     } 
    } 
} 
+0

非常感謝你,但這僅僅是我自己的每一個控制中心,所有我想要的是中心他們將保持彼此之間的距離 – vbtheory 2013-05-10 21:46:51

0

所以,我做這件事是這樣的:

public enum ArrangeOrientation : int { 
     None, 
     Horizonatal, 
     Vertical, 
     HorizontalGrid, 
     VerticalGrid, 
     TopLeftGrid, 
     TopRightGrid, 
     BottomLeftGrid, 
     BottomRightGrid 
    } 

    private void ArrangeButtons(List<Control> controls, List<Control> parents, ArrangeOrientation orientation, double shrinkFactor = 1d) { 
     if(controls == null) return; 
     if(parents == null) parents = new List<Control>(); 
     List<Control> childs = new List<Control>(); 
     Control parent = null; 

     foreach(Control ctrl in controls) { 
      if(parent == null && !parents.Contains(ctrl.Parent)) { 
       parents.Add(ctrl.Parent); 
       parent = ctrl.Parent; 
      } 
      if(parent == ctrl.Parent) 
       childs.Add(ctrl); 
     } 
     if(parent != null && childs.Count > 0) { 
      ArrangeControlsToGridLayout(childs, orientation, shrinkFactor); 
      ArrangeButtons(controls, parents, orientation, shrinkFactor); 
     } 
    } 

    private void ArrangeControlsToGridLayout(List<Control> controls, ArrangeOrientation orientation, double shrinkFactor = 1d) { 
     // do nothing if nothing set 
     if(orientation == ArrangeOrientation.None) return; 
     if(shrinkFactor == 0d|| shrinkFactor > 1d) shrinkFactor = 1d; 

     // buffer controls in separate list to avoid manipulating parameter 
     List<Control> ctrl = new List<Control>(controls.ToArray()); 
     // remove invisible controls 
     int j = 0; 
     while(j < ctrl.Count) { 
      if(!ctrl[j].Visible) ctrl.RemoveAt(j); 
      else j++; 
     } 

     // loop arrangement 
     int count = ctrl.Count; 
     int xDelta, yDelta, xOffs, yOffs, y, x, columns, rows, parentWidth, parentHeight, xShrinkOffs, yShrinkOffs; 
     if(count >= 1) { 

      // parents size 
      parentWidth = ctrl[0].Parent.Width; 
      parentHeight = ctrl[0].Parent.Height; 
      // shrink factor offset 
      parentWidth = Convert.ToInt32(parentWidth * shrinkFactor); 
      parentHeight = Convert.ToInt32(parentHeight * shrinkFactor); 
      // shrink factor offset 
      xShrinkOffs = Convert.ToInt32((ctrl[0].Parent.Width - parentWidth)/2d); 
      yShrinkOffs = Convert.ToInt32((ctrl[0].Parent.Height - parentHeight)/2d); 

      // calculate columns rows grid layout        
      if(orientation == ArrangeOrientation.Horizonatal) { 
       rows = 1; 
       columns = count; 
      } 
      else if(orientation == ArrangeOrientation.Vertical) { 
       rows = count; 
       columns = 1; 
      } 
      else if(orientation == ArrangeOrientation.TopLeftGrid 
       || orientation == ArrangeOrientation.TopRightGrid 
       || orientation == ArrangeOrientation.BottomLeftGrid 
       || orientation == ArrangeOrientation.BottomRightGrid) { 
       rows = 1; 
       columns = count; 
      } 
      else { 
       rows = Convert.ToInt32(Math.Floor(Math.Sqrt(count))); 
       if(Math.Sqrt(count) % 1d != 0d) rows++; 
       columns = count/rows + (count % rows != 0 ? 1 : 0); 
      } 
      if(orientation == ArrangeOrientation.HorizontalGrid) { 
       int swap = columns; 
       columns = rows; 
       rows = columns; 
      } 

      // calculate position offsets, grid distance 
      xDelta = parentWidth/count; 
      yDelta = parentHeight/count; 
      xOffs = xDelta/2; 
      yOffs = yDelta/2;     
      if(orientation == ArrangeOrientation.TopLeftGrid) {              
      } 
      else if(orientation == ArrangeOrientation.TopRightGrid) { 
       xOffs = parentWidth - xOffs; 
       xDelta = -xDelta; 
      } 
      else if(orientation == ArrangeOrientation.BottomLeftGrid) { 
       yOffs = parentHeight - yOffs; 
       yDelta = -yDelta; 
      } 
      else if(orientation == ArrangeOrientation.BottomRightGrid) { 
       xOffs = parentWidth - xOffs; 
       yOffs = parentHeight - yOffs; 
       xDelta = -xDelta; 
       yDelta = -yDelta; 
      } 
      else { 
       xDelta = parentWidth/columns; 
       yDelta = parentHeight/rows; 
       xOffs = xDelta/2; 
       yOffs = yDelta/2; 
      } 

      // fit controls in grid layout    
      Point pRoot = new Point(/*ctrl[0].Parent.Location.X + */xOffs, /*ctrl[0].Parent.Location.Y + */yOffs); 
      y = 0; x = 0; 
      for(int i = 0; i < count; i++) { 

       if(orientation == ArrangeOrientation.VerticalGrid) { 
        // actual x/y - points zero based index 
        y = Convert.ToInt32(Math.Floor((double)i % rows)); 
        // next row? zero based index 
        if(i % rows == 0 && i != 0) x++; 
       } 
       else { 
        // actual x/y - points zero based index 
        x = Convert.ToInt32(Math.Floor((double)i % columns)); 
        // next row? zero based index 
        if(i % columns == 0 && i != 0) y++; 
        if(orientation == ArrangeOrientation.TopLeftGrid 
         || orientation == ArrangeOrientation.TopRightGrid 
         || orientation == ArrangeOrientation.BottomLeftGrid 
         || orientation == ArrangeOrientation.BottomRightGrid) 
         y = x; 
       }     // assign controls to grid 
       ctrl[i].Location = new Point(pRoot.X + x * xDelta - ctrl[i].Size.Width/2 + xShrinkOffs, pRoot.Y + y * yDelta - ctrl[i].Size.Height/2 + yShrinkOffs); 

      } 
     } 
    } 
0

當有多個控件,上面的代碼是將所有的控制之上彼此。

我所要做的就是將面板中的所有控件居中,但將它們放在彼此的旁邊,而不是將其放在另一面。

這裏是我修改後的代碼(FYI這將中控在1號線沒有多線):

public enum Direction 
    { 
     Vertical, 
     Horizontal, 
     Both 
    } 

    public void CenterControls(List<Control> controls, Direction direction) 
    { 
     if (controls.Count > 1) 
     { 
      int controls_sum_width = 0; 
      int controls_seperation = 20; 
      int parentwidth = 0;    

      Point center; 
      foreach (Control ctl in controls) 
      { 
       controls_sum_width = controls_sum_width + ctl.Width + controls_seperation; 
      } 

      Point Container_center = new Point(controls[0].Parent.Width/2, controls[0].Parent.Height/2); 
      parentwidth = controls[0].Parent.Width; 
      int xoffset = (parentwidth - controls_sum_width)/2; 


      int Location_X = 0; 
      foreach (Control ctl in controls) 
      { 
       center = new Point(ctl.Width/2, ctl.Height/2); 
       int yOffset = Container_center.Y - center.Y; 
       switch (direction) 
       { 
        case Direction.Vertical: 
         ctl.Location = new Point(ctl.Location.X + xoffset, ctl.Location.Y); 
         break; 

        case Direction.Horizontal: 
         ctl.Location = new Point(ctl.Location.X, yOffset); 
         break; 

        case Direction.Both: 
         ctl.Location = new Point(Location_X + xoffset, yOffset); 
         break; 
       } 
       Location_X = Location_X + ctl.Width+ controls_seperation; 
      } 
     } 
     else 
     { 
      Point parent_center; 
      Point center; 
      parent_center = new Point(controls[0].Parent.Width/2, controls[0].Parent.Height/2); 
      center = new Point(controls[0].Location.X + controls[0].Width/2, controls[0].Location.Y + controls[0].Height/2); 
      int xOffset = parent_center.X - center.X; 
      int yOffset = parent_center.Y - center.Y; 
      switch (direction) 
      { 
       case Direction.Vertical: 
        controls[0].Location = new Point(controls[0].Location.X + xOffset, controls[0].Location.Y); 
        break; 

       case Direction.Horizontal: 
        controls[0].Location = new Point(controls[0].Location.X, controls[0].Location.Y + yOffset); 
        break; 

       case Direction.Both: 
        controls[0].Location = new Point(controls[0].Location.X + xOffset, controls[0].Location.Y + yOffset); 
        break; 
      } 
     } 
    } 

    public void GetAllControl(Control c, List<Control> list) 
    { 
     //gets all controls and saves them to a list 
     foreach (Control control in c.Controls) 
     { 
      list.Add(control); 
     } 
    } 
相關問題