2013-05-10 68 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); 
     } 
    } 
相关问题