This is my code:
for (int i = 0; i < gBoxes.Length; i++)
{
var LabelID = new Label();
gLabels[i] = LabelID;
LabelID.Font = new System.Drawing.Font("Arial", 7.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
LabelID.Name = "label" + i;
LabelID.Text = gColumns[i];
LabelID.Location = new System.Drawing.Point(12, StartLoc);
this.Controls.Add(LabelID);
iPanel.Controls.Add(LabelID);
var BoxID = new TextBox();
gBoxes[i] = BoxID;
BoxID.Font = new System.Drawing.Font("Arial", 7.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
BoxID.Name = "textbox" + i;
BoxID.Text = gContent[i];
BoxID.Location = new System.Drawing.Point(12, StartLoc);
BoxID.Size = new System.Drawing.Size(240, 19);
this.Controls.Add(BoxID);
iPanel.Controls.Add(BoxID);
StartLoc += 25;
}
Which works fine, however, the labels overlap the boxes. Which would be the best method to place the boxes after the labels, and that the boxes are aligned together.
Result:
Set the Label.AutoSize property to true. (The default value when adding them in the designer is true but the default when adding by code is false.) Also set your TextBox.Location to have a larger x value than your label... you have the starting location of label and textbox at the same x value of 12.
You can also use the AutoSize property to determine how wide the labels are and then place the textboxes accordingly. Add your labels with AutoSize = true. Arrange the text boxes by determining the widest label and resetting the TextBox.Location just to the right of them. Here is an example:
public partial class Form1 : Form
{
public int YPos { get; set; }
List<string> Labels = new List<string>();
List<Label> LabelControls = new List<Label>();
List<TextBox> TextBoxControls = new List<TextBox>();
public Form1()
{
InitializeComponent();
AddRow("medium string", "medium");
AddRow("This is a longer string", "long");
AddRow("l", "little");
Arrange();
}
void AddRow(string label, string value)
{
Labels.Add(label);
var LabelID = new Label();
LabelID.AutoSize = true; // make sure to enable AutoSize
LabelID.Font = new System.Drawing.Font("Arial", 7.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
LabelID.Name = "label" + Labels.Count;
LabelID.Text = label;
LabelID.Location = new System.Drawing.Point(12, YPos);
this.Controls.Add(LabelID);
panel1.Controls.Add(LabelID);
LabelControls.Add(LabelID);
var BoxID = new TextBox();
BoxID.Font = new System.Drawing.Font("Arial", 7.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
BoxID.Name = "textbox" + Labels.Count;
BoxID.Text = value;
BoxID.Location = new System.Drawing.Point(12, YPos);
BoxID.Size = new System.Drawing.Size(240, 19);
this.Controls.Add(BoxID);
panel1.Controls.Add(BoxID);
TextBoxControls.Add(BoxID);
// both controls have the same Y location
// and initially will have the same X location
YPos += 25;
}
void Arrange()
{
// determine the widest label sized by the AutoSize
int maxLabelX = 0;
for (int i = 0; i < Labels.Count; i++)
{
maxLabelX = Math.Max(maxLabelX, LabelControls[i].Location.X + LabelControls[i].Size.Width);
}
// move all the text boxes a little to the right of the widest label
for (int i = 0; i < Labels.Count; i++)
{
TextBoxControls[i].Location = new Point(maxLabelX + 10, TextBoxControls[i].Location.Y);
}
}
}
The above code generates properly placed TextBox controls:
Related
I'm working in a c# application in winform.
I saw that there is no Style for element (unlike WPF). But is there a way to simply set all the labels to a specific design ?
Actually I do :
public partial class myControl : UserControl
{
private Color LabelColor = Color.Indigo;
private Color LabelFont = new System.Drawing.Font("Arial",
18F,
System.Drawing.FontStyle.Regular,
System.Drawing.GraphicsUnit.Point,
((byte)(0)));
public myControl()
{
InitializeComponent();
//Set design
designLabels();
}
private void designLabels()
{
List<Label> labelsToStyle = new List<Label>();
labelsToStyle.Add(labelName);
labelsToStyle.Add(labelAge);
labelsToStyle.Add(labelSize);
foreach (Label l in labelsToStyle)
{
l.ForeColor = LabelColor;
l.Font = LabelFont;
l.Dock = DockStyle.Fill;
}
}
}
It works but it doesn't display correctly in designer (I have to run application to see my design). And maybe it exists a simplest way ?
As per my comment the easiest is to create a custom control and use that one in your windows.
here how simple it is. Simply override the label and set in constructor the default value you want
public class DesignLabel : Label
{
public DesignLabel()
{
ForeColor = Color.Indigo;
Font = new System.Drawing.Font("Arial", 18F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
}
}
then compile once and go to your design view, open your toolbox and you will see the "DesignLabel", simply drag drop on the window and that's it. If you change default in the class it will be changed all over the place.
If you want to change the style already at design time so that you can see in in the Form.cs[design] you need to edit the Form.Designer.cs file! But this you have to do label for label by hand. I saved in this example the Font and Color in the project properties (sorry for the german version):
in my example I have 3 Labels. In the Form.Designer.cs file you can add the properties:
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(12, 9);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(41, 15);
this.label1.TabIndex = 0;
this.label1.Text = "label1";
this.label1.Font = Properties.Settings.Default.LabelFont;
this.label1.ForeColor = Properties.Settings.Default.LabelColor;
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(12, 68);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(41, 15);
this.label2.TabIndex = 1;
this.label2.Text = "label2";
this.label2.Font = Properties.Settings.Default.LabelFont;
this.label2.ForeColor = Properties.Settings.Default.LabelColor;
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(12, 122);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(41, 15);
this.label3.TabIndex = 2;
this.label3.Text = "label3";
this.label3.Font = Properties.Settings.Default.LabelFont;
this.label3.ForeColor = Properties.Settings.Default.LabelColor;
The result looks like this:
DISCLAIMER
I would not recommend this approach! Editing the Form.Desginer.cs file is never a good idea! I would stick to the run time changes. If you want to change all Labels just filter the this.Controls for it and foreach through the collection like this:
this.Controls.OfType<Label>().ToList().ForEach(lbl =>
{
lbl.Font = LabelFont;
lbl.ForeColor = LabelColor;
//lbl.Dock = DockStyle.Fill; // uncommented, because I could see only 1 Label
});
The result will be the same.
I have this custom control which is basically a panel:
class ResultPanel : Panel {
Label scoreValueLabel = new Label();
public ResultPanel() : base(){
scoreValueLabel.AutoSize = true;
scoreValueLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 15F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
scoreValueLabel.Location = new System.Drawing.Point(265, 99);
scoreValueLabel.Name = "scoreValueLabel";
scoreValueLabel.Size = new System.Drawing.Size(49, 25);
scoreValueLabel.TabIndex = 10;
scoreValueLabel.Text = "+10";
Controls.Add(scoreValueLabel);
}
}
And I'm trying to add it to a panel in an event handler:
private void ResultsReceivedHandler(object sender, List<QuestionResult> results) {
ResultPanel resultPanel = new ResultPanel();
allResultsPanel.Controls.Add(new ResultPanel());
resultPanel.Anchor = ((AnchorStyles.Top | AnchorStyles.Left) | AnchorStyles.Right);
resultPanel.BorderStyle = BorderStyle.FixedSingle;
resultPanel.Location = new Point(0, 155);
resultPanel.Name = "questionResultPanel";
resultPanel.Size = new Size(325, 148);
resultPanel.TabIndex = 0;
}
I know that an instance of ResultPanel can be displayed in allResultsPanel because I have added(using designer view) a ResultPanel to allResultsPanel that has the same size as this one at the top of allResultsPanel and that displays.
allResultsPanel is just a normal Panel btw, and its big enough to fit the control because its height is 800.
So why can i see the control added through the design view but not one added dynamically?
While setting up resultPanel:
ResultPanel resultPanel = new ResultPanel();
resultPanel.Anchor = ((AnchorStyles.Top | AnchorStyles.Left) | AnchorStyles.Right);
resultPanel.BorderStyle = BorderStyle.FixedSingle;
resultPanel.Location = new Point(0, 155);
resultPanel.Name = "questionResultPanel";
resultPanel.Size = new Size(325, 148);
resultPanel.TabIndex = 0;
You are adding another new panel to the allResultsPanel
allResultsPanel.Controls.Add(new ResultPanel());
i have a button in my form and for every button click it is adding groupBox. but i want a winform contain only 8 groupboxes. when the numbers of groupBox reach 8 it will automatically do Visible=false all 8 before groupBox and again adds a groupBox named(groupBox9). what must i do?
private void butonYeni_Click(object sender, EventArgs e)
{
//creating Font
Font font = new Font("Microsoft Sans Serif", 10.0f, FontStyle.Bold);
Font font2 = new Font("Microsoft Sans Serif", 9.0f, FontStyle.Bold);
int sayGB = 0;
foreach (Control c in this.Controls)
{
if (c.GetType() == typeof(GroupBox))
{
sayGB++;
}
for (int i = sayGB; i < 1000; i++)
{
//creating groupbox
GroupBox Group = new GroupBox();
Group.Width = 767;
Group.Height = 179;
Group.Text = "Soru & Cevap";
Group.Font = font;
Group.ForeColor = Color.Maroon;
Group.Location = new Point(200,66);
//creating label
Label Soru = new Label();
Soru.Text = "Soru: ";
Soru.Font = font2;
Soru.ForeColor = Color.Maroon;
Soru.Location = new Point(6,33);
Soru.Width = 53;
Soru.Height = 13;
//creating textbox
TextBox soruText = new TextBox();
soruText.Width = 685;
soruText.Height = 20;
soruText.Font = font2;
soruText.ForeColor = Color.Black;
soruText.Multiline = true;
soruText.Location = new Point(70,31);
//creating label
Label Cevap = new Label();
Cevap.Text = "Cevap:";
Cevap.Font = font2;
Cevap.ForeColor = Color.Maroon;
Cevap.Location = new Point(6, 92);
Cevap.Width = 53;
Cevap.Height = 25;
//creating textbox
TextBox cevapText = new TextBox();
cevapText.Width = 685;
cevapText.Height = 69;
cevapText.Font = font2;
cevapText.ForeColor = Color.Black;
cevapText.Multiline = true;
cevapText.Location = new Point(70,67);
//creating button
Button btn = new Button();
btn.Width = 75;
btn.Height = 25;
btn.Text = "Kaydet";
btn.BackColor = Color.Maroon;
btn.Font = font2;
btn.ForeColor = Color.White;
btn.Location = new Point(682,148);
//kontrolleri ekleme
Group.Controls.Add(btn);
Group.Controls.Add(Soru);
Group.Controls.Add(soruText);
Group.Controls.Add(Cevap);
Group.Controls.Add(cevapText);
this.Controls.Add(Group);
}
}
}
define an integer class variable and increase it everytime the button is clicked. After increasing it, check if it's greater than 8. If it is, set your stuff to Visible = false.
Mock up:
public class MyClass
{
private int groupboxCounter = 0;
public MyClass()
{
}
private void btn_click(...)
{
// add a new groupbox here
groupboxCounter++;
if (groupboxCounter > 8)
{
//make stuff invisible here
}
}
}
I have a few tablelayoutpanels in my program in order to lay out different controls in rows. Until recently these were all working correctly, but after a change in server this is no longer the case. A potential cause is a change in screen resolution as I noticed similar problems on other computers running my program.
An example of this problem is shown below
Before the data rows are loaded (from database), the sizing is incorrect. A measurement using the VS designer shows that the size in figure 2 is correct. Interestingly, if I add a blank row to this table then the resizing doesn't happen.
public JobOpMainTable()
{
DoubleBuffered = true;
AutoSize = true;
AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
DoubleBuffered = true;
BackColor = Color.White;
CellBorderStyle = TableLayoutPanelCellBorderStyle.Single;
headers();
}
private void headers()
{
string[] names = { "Operation", "Est Lab Hrs", "Est UM Hrs", "Act Lab Hrs", "Act UM Hrs" };
for (int i = 0; i < names.Length; i++) header(names[i], i);
}
private void header(string name, int col)
{
Panel pan = new Panel();
pan.Width = widths[col];
pan.Height = 25;
pan.BackColor = Color.Black;
pan.Dock = DockStyle.Fill;
pan.Margin = new System.Windows.Forms.Padding(0);
TextBox txt = new TextBox();
txt.Font = new System.Drawing.Font("Microsoft sans serif", 8, FontStyle.Bold);
txt.Text = name;
txt.ReadOnly = true;
txt.BackColor = Color.Black;
txt.ForeColor = Color.White;
txt.Dock = DockStyle.Fill;
txt.BorderStyle = System.Windows.Forms.BorderStyle.None
pan.Controls.Add(txt);
Controls.Add(pan, col, 0);
}
private int newRow()
{
int row = Controls.Count / 5;
for (int i = 0; i <= 4; i++)
{
TextBox txt = new TextBox();
txt.Width = widths[i];
txt.BackColor = Color.White;
txt.BorderStyle = System.Windows.Forms.BorderStyle.None;
txt.ReadOnly = true;
txt.Dock = DockStyle.Fill;
txt.Margin = new Padding(0);
txt.Enter += new EventHandler(enterCell);
txt.Leave += new EventHandler(leaveCell);
Controls.Add(txt, i, row);
}
return row;
}
Above is the code I believe is relevant to the problem. The resizing occurs the first time newRow() is called when loading in data: each new box makes the column wider. Again though, the odd thing is this doesn't occur if I add a row from the constructor
I have this code to create a new label with a variable attached to it but I get an error (obviously). Is there a way to do this?
System.Windows.Forms.Label lbl_Task[i] = new System.Windows.Forms.Label();
I.e, if i == 4, the label would be called lbl_Task4. If i == 9, it would be lbl_Task9, etc.
Edit:
New code shows:
for (int i = 0; i < rows; i++)
{
//create a label for the Task Name
Label lbl = new Label();
lbl.Name = "lbl_Task" + i;
tableLayoutPanel1.SetColumnSpan(lbl, 4);
lbl.Dock = System.Windows.Forms.DockStyle.Fill;
lbl.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
lbl.Location = new System.Drawing.Point(3, pointInt);
lbl.Size = new System.Drawing.Size(170, 24);
lbl.TabIndex = 8;
lbl.Text = Convert.ToString(dtTasks.Rows[i]["Task_Name"]);
lbl.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
this.Controls.Add(lbl);
pointInt += 24;
}
This compiles but does not show on my win form when I debug. Any ideas?
You are looking for something like this:
for(int i =0; i<10; i++)
{
Label lbl = new Label();
lbl.Name = "lbl_Task" + i;
// set other properties
this.Controls.Add(lbl);
}
Use a collection of Lables and try like this
List<Label> labels = new List<Label>();
for (int i = 0; i < 100; i++)
{
Label label = new Label();
// Set Lable properties
yourLayoutName.Controls.Add(label);//add the lable
labels.Add(label);
}