In my project I wanted to order controls at run-time, like in DataGridView how we'll use display-index to order fields in the grid.
In design level I added 3 TextBoxs and 1 ComboBox next to each other & in run time i wanted to order them, for example, first 2 TextBoxs should show, then the ComboBox and then the other TextBox.
Is it possible to rearrange the controls in run-time?
Every Control in Windows Forms has a Location property. You can easily change the location of the control by changing this property:
textBox1.Location = new Point(10, 50); // Puts the TextBox at coordinates (10,50)
The coordinates are relative to upper-left corner of the control container (the form itself for example).
In your case, you can easily arrange the controls like this:
Control[] controls = new Control[] { textBox1, textBox2, comboBox3, textBox3 }; // These are your controls
int left = 20, top = 50; // or any other value
foreach (c in controls)
{
c.Location = new Point(left, top);
left += c.Width + 10; // space 10 pixels between controls
}
Related
This question already has an answer here:
Alignment of Items in GroupBox
(1 answer)
Closed 4 years ago.
I've created window applications and would like to center elements in the groupbox. Can I do this with a code?
groupbox
This code assumes you will be creating the additional controls entirely in code and not using the Designer.
If you do use the Designer, just remove the line
Button button = new Button() { Text = "Button1" };
and put the name of the button control in the next line.
private void AddControlsToGroupBox()
{
Button button = new Button() { Text = "Button1" };
CentreControlInGroupBox(this.groupBox1, button);
}
private void CentreControlInGroupBox(GroupBox theGroupBox, Control theControl)
{
// Find the centre point of the Group Box
int groupBoxCentreWidth = theGroupBox.Width / 2;
int groupBoxCentreHeight = theGroupBox.Height / 2;
// Find the centre point of the Control to be positioned/added
int controlCentreWidth = theControl.Width / 2;
int controlCentreHeight = theControl.Height / 2;
// Set the Control to be at the centre of the Group Box by
// off-setting the Controls Left/Top from the Group Box centre
theControl.Left = groupBoxCentreWidth - controlCentreWidth;
theControl.Top = groupBoxCentreHeight - controlCentreHeight;
// Set the Anchor to be None to make sure the control remains
// centred after re-sizing of the form
theControl.Anchor = AnchorStyles.None;
// Add the control to the GroupBox's Controls collection to maintain
// the correct Parent/Child relationship
theGroupBox.Controls.Add(theControl);
}
The code also assumes you will place only a single control in the Group Box. I don't think you will find it too hard to adjust the sample accordingly if there are multiple controls.
I created a template panel to go by when my form loads that holds a record. When adding a new record I have a method that duplicates that template panel and then adds it to my list of panels for each record. Somehow controls are getting deleted from my template panel when I am duplicating it and I have no idea how this is happening. The portion of code doing this is listed below
Panel pn = new Panel()
{
Width = _PNTemp.Width,
Height = _PNTemp.Height,
Left = 0,
Top = 0,
BackColor = _PNTemp.BackColor,
ForeColor = _PNTemp.ForeColor,
AutoScroll = true,
Name = _PNTemp.Name,
Tag = _PrgPanels.Count.ToString()
};
MessageBox.Show(_PNTemp.Controls.Count.ToString());
foreach (Control c in _PNTemp.Controls)
{
pn.Controls.Add(c);
MessageBox.Show(_PNTemp.Controls.Count.ToString());
}
MessageBox.Show(_PNTemp.Controls.Count.ToString());
_PrgPanels.Add(pn);
I put the messagebox.show() in at 3 points to narrow down where it is happening. The first one shows the correct number of controls, the second and third shows a 1/2 the total amount of controls. why is this?
This is because each control can be added to only one parent control. All controls in your template panel are already a child of the template panel. When you try to add these controls to a new panel, the controls will get removed from the template panel.
As per the docs:
A Control can only be assigned to one Control.ControlCollection at a
time. If the Control is already a child of another control it is
removed from that control before it is added to another control.
Which means that you need to create new controls instead of adding those in the template.
An alternative approach is to create a method that returns the template panel. When you need the template panel, just call the method and a new panel will be created:
public static Panel CreateTemplatePanel() {
Panel pn = new Panel();
// set properties, add controls...
return pn;
}
A control can only be on one panel at once. I've added comments inline in your code to help explain whats happening.
Panel pn = new Panel()
{
Width = _PNTemp.Width,
Height = _PNTemp.Height,
Left = 0,
Top = 0,
BackColor = _PNTemp.BackColor,
ForeColor = _PNTemp.ForeColor,
AutoScroll = true,
Name = _PNTemp.Name,
Tag = _PrgPanels.Count.ToString()
};
MessageBox.Show(_PNTemp.Controls.Count.ToString());
//all the controls are still inside _PNTemp
foreach (Control c in _PNTemp.Controls)
{
pn.Controls.Add(c);
MessageBox.Show(_PNTemp.Controls.Count.ToString());
//Each time this runs you remove a control from _PNTemp to pn.
}
//All the controls moved from _PnTemp to pn
MessageBox.Show(_PNTemp.Controls.Count.ToString());
_PrgPanels.Add(pn);
I would like to create a few panel dynamically in my window form application. Each panel will consist of 3 labels and one text box and one button. Now I know I can hard code this all at once by declaring each variable every time, but it takes a lot of coding and it is obviously not efficient at all.
So my question is: Is there a way to create pre-define panel dynamically where each time a panel is created will have a predefined layout setup already. So all i need to do is to add a panel, its location and size every time, and all the content(like labels, text-box and button) inside the panel are already setup with their location associated with the panel itself. Do I really have to create a class just for that?
Thanks in advance for read and taking your time.
Create Windows Forms control or user control, see http://msdn.microsoft.com/en-us/library/6hws6h2t.aspx
Create a user control, and place on it whatever you like (your labels). Expose public methods/properties of that control so you can control the contents of it. Place as many of those on the form as you like, they will all look and behave same.
Here is an example you can play with...
for (int i = 1; i < 5; i++)
{
var panel1 = new Panel() { Size = new Size(90, 80), Location = new Point(10, i * 100), BorderStyle = BorderStyle.FixedSingle };
panel1.Controls.Add(new Label() { Text = i.ToString(), Location = new Point(10, 20) });
panel1.Controls.Add(new Label() { Text = i.ToString(), Location = new Point(10, 40) });
panel1.Controls.Add(new Label() { Text = i.ToString(), Location = new Point(10, 60) });
Controls.Add(panel1);
}
I have a class which generates a form and controls. The controls vary between buttons, radio controls, check boxes and labels. The idea is to neatly create the form with a label above each control. The problem is that I cannot seem to find the formula or way to neatly organise/space them. It works fine when I have just text boxes, but I'm not sure how to handle larger controls, like check box lists. Here's an example of how I handle text boxes:
case "Text":
TextBox tbx = new TextBox();
tbx.Name = df.Value.Name;
tbx.Text = (df.Value.DefValue != null) ? df.Value.DefValue : "";
tbx.Location = new Point(lbl.Location.X, lbl.Location.Y + 20);
f.Controls.Add(tbx);
break;
Mind that this is all in a foreach loop. This is the part that precedes it (label):
if (i == 0)
{
lbl.Location = new Point(10, 10);
}
else
{
lbl.Location = new Point(10, (i * 50) + 10);
}
This neatly sorts the text boxes and labels out with an even spacing. Can anyone offer me some advice on how to handle different controls? I want to place them underneath eachother but keep at least 10 pixels spacing from the bottom of each control to the top of the next label.
Thank you in advance.
Use a tablelayout. You can take a look at how the designer does it in the code behind file.
For the spacing, fill in the "margin" property of your controls. 5 on top and 5 at the bottom should do it.
I have UserControl that holds Infragistics Graph control. On the TreeView sub node's right click, I have context menu as "Create Graph". This will create the new graph. This is about what i going to do.
I have confusion about what layout to use. Whether FlowLayoutPanel or TableLayoutPanel or anything else. If only one graph is add --> graph has to occupy the full form. If two graph are added --> two graph's has to split the space and so on.This is only in the format of one after another. ie First graph at top, second is below to first ..so on.
If UserControl is manually changed it should not affect the size where we displaying.
This is the WinForm. Currently i using FlowLayoutPanel, i creating panel with the constant size and added the UserControl with DockStyle.Fill. Then i added the Panel to the FlowLayoutPanel.
GraphUserControl usr = new GraphUserControl();
usr.Dock = DockStyle.Fill;
Panel pnl = new Panel();
pnl.Controls.Add(usr);
flowLayoutpnl.Controls.Add(pnl);
What is the best approach to do this?.
A TableLayoutPanel is probably your best choice, as the row heights can be set to a percentage value.
private void AddControl(Control ctl)
{
tableLayoutPnl.RowCount += 1;
tableLayoutPnl.RowStyles.Add(
new RowStyle(SizeType.Percent, 100F / tableLayoutPnl.RowCount));
ctl.Dock = DockStyle.Fill;
tableLayoutPnl.Controls.Add(ctl, 0, tableLayoutPnl.RowCount - 1);
foreach (RowStyle rs in tableLayoutPnl.RowStyles)
{
rs.Height = 100F / tableLayoutPnl.RowCount;
}
}
You can then call this as follows:
GraphUserControl usr = new GraphUserControl();
AddControl(usr);