How to layout items in winform - c#

I am working on a homework c# winforms project and would like to add date and time in top right corner of my main form in a way that in first row I have a date written in one label, and on second row I have time written in second label.
Also I need that those stick in the top right corner if form is resized.
I don't know if it matters, but those label controls are inside panel which is top docked in form, and this panel already contains two controls that are docked left.
example of what I want
I've been playing with anchor and dock properties but I can't get it to work in a way I want.
private void GlavnaForma_Load(object sender, EventArgs e)
{
timerDateTime.Start();
lblDate.Text = DateTime.Now.ToString("dddd, dd.M.yyyy", new CultureInfo("hr-HR"));
lblTime.Text = DateTime.Now.ToString("HH:mm:ss", new CultureInfo("hr-HR"));
}
private void timerDateTime_Tick(object sender, EventArgs e)
{
lblDate.Text = DateTime.Now.ToString("dddd, dd.M.yyyy", new CultureInfo("hr-HR"));
lblTime.Text = DateTime.Now.ToString("HH:mm:ss", new CultureInfo("hr-HR"));
}

Set the anchor to Top, Right like so:

There are several ways to do this.
I would probably make the main form have a table layout panel with one column and three rows. Make the top two rows be absolutely sized and the third row have size type "percent" with a value of 100.0% to take up all remaining room. Then put a label each in the top two rows and justify the labels to the right via setting their "Dock" property to "Right".
All of this can be done in the form designer GUI. The generated code looks like the following:
this.tableLayout = new System.Windows.Forms.TableLayoutPanel();
this.labelDate = new System.Windows.Forms.Label();
this.labelTime = new System.Windows.Forms.Label();
this.tableLayout.SuspendLayout();
this.SuspendLayout();
//
// tableLayout
//
this.tableLayout.ColumnCount = 1;
this.tableLayout.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayout.Controls.Add(this.labelDate, 0, 0);
this.tableLayout.Controls.Add(this.labelTime, 0, 1);
this.tableLayout.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayout.Location = new System.Drawing.Point(0, 0);
this.tableLayout.Name = "tableLayout";
this.tableLayout.RowCount = 3;
this.tableLayout.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 24F));
this.tableLayout.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 24F));
this.tableLayout.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayout.Size = new System.Drawing.Size(800, 450);
this.tableLayout.TabIndex = 0;
//
// labelDate
//
this.labelDate.AutoSize = true;
this.labelDate.Dock = System.Windows.Forms.DockStyle.Right;
this.labelDate.Location = new System.Drawing.Point(742, 0);
this.labelDate.Name = "labelDate";
this.labelDate.Size = new System.Drawing.Size(55, 24);
this.labelDate.TabIndex = 0;
this.labelDate.Text = "26-8-2019";
//
// labelTime
//
this.labelTime.AutoSize = true;
this.labelTime.Dock = System.Windows.Forms.DockStyle.Right;
this.labelTime.Location = new System.Drawing.Point(748, 24);
this.labelTime.Name = "labelTime";
this.labelTime.Size = new System.Drawing.Size(49, 24);
this.labelTime.TabIndex = 1;
this.labelTime.Text = "19:59:58";
Add whatever further content you want to the third row. Maybe add a panel to that row docked to "Fill"

Related

in c# winform, How to keep a control always in the center bottom of a form when form's size changed?

in c# winform, How to keep a control always in the center bottom of a form when form's size changed?
if I use DockStyle.Bottom, I can't set its width.
I tried it out. The following is the code, but I don't know why? It's mainly because I don't understand why the Left value will change when the Anchor. Bottom is set?
public void Run()
{
Form form = new Form();
form.Width = 600;
form.Height = 600;
Button btnOK = new Button();
btnOK.Text = "OK";
btnOK.Left = form.ClientSize.Width / 2 - btnOK.Width;
btnOK.Top = 0;
btnOK.Anchor = AnchorStyles.Bottom;
Button btnCancel = new Button();
btnCancel.Text = "Cancel";
btnCancel.Left = form.ClientSize.Width / 2;
btnCancel.Top = 0;
btnCancel.Anchor = AnchorStyles.Bottom;
Panel panel = new Panel();
panel.Height = btnOK.Height;
panel.Width = form.ClientSize.Width;
panel.Dock = DockStyle.Bottom;
panel.Controls.Add(btnOK);
panel.Controls.Add(btnCancel);
form.Controls.Add(panel);
form.Show();
}
Use a TableLayoutPanel. You can Dock it to the Bottom or Anchor it to the Bottom, Left and Right. You would have one row then have a column with an absolute width for each control and one extra column on the left and another on the right with 50% width. Those two extra columns will take up half the empty space each, thus keeping the others in the middle.

Open a Form under a DataGridView Cell

I try to open a form just below a DataGridView header cell. I have this (and it is not working):
private void button1_Click(object sender, EventArgs e)
{
Form aForm = new Form();
aForm.Text = #"Test";
aForm.Top = this.Top + dataGridView1.Top - dataGridView1.GetCellDisplayRectangle(0, 0, false).Height;
aForm.Left = this.Left + dataGridView1.GetCellDisplayRectangle(0, 0, false).Left;
aForm.Width = 25;
aForm.Height = 100;
aForm.ShowDialog();
}
I don't see how to get the right top and left based on the DataGridView cell.
Should you consider to use a Form, you have to calculate its Location using Screen coordinates:
Form form = new Form();
form.StartPosition = FormStartPosition.Manual;
form.FormBorderStyle = FormBorderStyle.FixedSingle;
form.Size = new Size(dataGridView1.Columns[dataGridView1.CurrentCell.ColumnIndex].Width, 100);
Point c = dataGridView1.PointToScreen(dataGridView1.GetCellDisplayRectangle(
dataGridView1.CurrentCell.ColumnIndex,
dataGridView1.CurrentCell.RowIndex, false).Location);
form.Location = new Point(c.X, c.Y);
form.BringToFront();
form.Show(this);
If you find youself in trouble using a Form, you might consider using a Panel instead:
Point c = dataGridView1.PointToScreen(dataGridView1.GetCellDisplayRectangle(
dataGridView1.CurrentCell.ColumnIndex,
dataGridView1.CurrentCell.RowIndex, false).Location);
Point r = this.PointToClient(c);
panel1.Location = new Point(r.X, r.Y);
panel1.BringToFront();
Take also a look at How do I to get the current cell position x and y in a DataGridView?
and Position new form directly under Datagridview selected row of parent

Why flowlayoutPanel is extending horizontally?

I have set this flowLayoutPanel, the controls inside arrange well, till the last arrives to the bottom border of the panel, then the controls start arranging on the right side (forming another column) keepping the vertical flow. I just want one column.
this.panel.Anchor =
((System.Windows.Forms.AnchorStyles)
(((System.Windows.Forms.AnchorStyles.Top |
System.Windows.Forms.AnchorStyles.Bottom)| System.Windows.Forms.AnchorStyles.Right)));
this.panel.AutoScroll = true;
this.panel.BorderStyle = BorderStyle.None;
this.panel.FlowDirection = System.Windows.Forms.FlowDirection.TopDown;
this.panel.Location = new System.Drawing.Point(0, 184);
this.panel.Name = "myPanel";
this.panel.RightToLeft = System.Windows.Forms.RightToLeft.No;
this.panel.Size = new System.Drawing.Size(300, 371);
this.panel.TabIndex = 9;
Use
this.panel.FlowDirection = System.Windows.Forms.FlowDirection.LeftToRight;
instead of
this.panel.FlowDirection = System.Windows.Forms.FlowDirection.TopDown;
if you want only one column than please add below code to your application just after control added to your flowlayoutpanel
this.panel.SetFlowBreak(<<YOUR_ADDED_CONTROL_NAME>>, true);
Example
Button btn1 = new Button();
btn1.Text = "TEST";
btn1.Height = 30;
btn1.Width = 100;
this.panel.Controls.Add(btn1);
this.panel.SetFlowBreak(btn1, true);

TableLayoutPanel Extra Lines at the Top?

I have a tablelayout panel in which I am adding rows programmatically. When Adding rows to this container the first time the form is opened (using statement with new ValidationForm()) the table displays fine. Upon the second time, I get added rows at the top for some reason? See the picture here:
This does not affect the number of rows that I use, just displays extra lines. And the number of lines increases each time i close and open the form. Here is the code i use to add rows:
private void insertRow(Label label, dynamic control)
{
// Create Panel
var panel = new Panel();
// Set Object Properties
label.TextAlign = ContentAlignment.MiddleCenter;
label.Dock = DockStyle.Fill;
control.Dock = DockStyle.Fill;
panel.Dock = DockStyle.Fill;
//generate delete button
var delete = new Button();
delete.Text = "X";
delete.ForeColor = System.Drawing.Color.Red;
delete.MaximumSize.Height.Equals(40);
delete.Name = rowCount.ToString();
delete.Dock = DockStyle.Right;
delete.Click += new EventHandler(deleteRow);
// Add Controls to the panel
panel.Controls.Add(control);
panel.Controls.Add(delete);
// add controls
//tableLayoutPanel_Validations.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 48F));
tableLayoutPanel_Validations.RowCount = rowCount + 1;
tableLayoutPanel_Validations.Controls.Add(label, 0, rowCount);
tableLayoutPanel_Validations.Controls.Add(panel, 1, rowCount);
tableLayoutPanel_Validations.RowStyles.Add(new RowStyle(SizeType.AutoSize));
rowCount++;
}
rowCount is a private int that is set to 0 at runtime.
My first instinct is that the entire form would "reset" after the using statement. The form declaration is public partial class ValidationForm: Form {}
Using statement opening the form:
using (AVBuilder.ValidationForm validationBuilder = new AVBuilder.ValidationForm())
{
if (validationBuilder.ShowDialog() == DialogResult.OK)
{
// ADD ITEM TO Validations LIST
ListViewItem result = new ListViewItem(validationBuilder.resultObject + " : " + validationBuilder.resultName);
result.SubItems.Add(validationBuilder.resultJson);
result.ToolTipText = result.Text;
listView_Validations.Items.Add(result);
//MessageBox.Show(validationBuilder.resultJson);
}
}
Make sure the rowCount variable is not declared static, as it will not reset to 0 on a new form instance.

Using StatusStrip in C#

Consider System.Windows.Forms.StatusStrip. I have added a StatusStrip to my Windows Forms application, but I am having a few problems.
I would like to have a label anchored at the left and a progressbar anchored on the right in the StatusStrip, but I can't find a way to set these properties.
I then thought that I may need to create two StatusStrips and anchor them on either side of the bottom of the form... That didn't pan out; besides that, it just doesn't feel right.
Just set the Spring property on the label control to True and you should be good to go.
What you have to do is set the alignment property of your progressbar to right. Then set the LayoutStyle of the StatusStrip to HorizontalStackWithOverflow.
private void InitializeComponent()
{
this.statusStrip1 = new System.Windows.Forms.StatusStrip();
this.toolStripStatusLabel1 = new System.Windows.Forms.ToolStripStatusLabel();
this.toolStripProgressBar1 = new System.Windows.Forms.ToolStripProgressBar();
this.statusStrip1.SuspendLayout();
this.SuspendLayout();
//
// statusStrip1
//
this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.toolStripStatusLabel1,
this.toolStripProgressBar1});
this.statusStrip1.LayoutStyle = System.Windows.Forms.ToolStripLayoutStyle.HorizontalStackWithOverflow;
this.statusStrip1.Location = new System.Drawing.Point(0, 250);
this.statusStrip1.Name = "statusStrip1";
this.statusStrip1.Size = new System.Drawing.Size(467, 22);
this.statusStrip1.TabIndex = 0;
this.statusStrip1.Text = "statusStrip1";
//
// toolStripStatusLabel1
//
this.toolStripStatusLabel1.Name = "toolStripStatusLabel1";
this.toolStripStatusLabel1.Size = new System.Drawing.Size(117, 17);
this.toolStripStatusLabel1.Text = "toolStripStatusLabel1";
//
// toolStripProgressBar1
//
this.toolStripProgressBar1.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right;
this.toolStripProgressBar1.Name = "toolStripProgressBar1";
this.toolStripProgressBar1.Size = new System.Drawing.Size(100, 16);
}
private System.Windows.Forms.StatusStrip statusStrip1;
private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabel1;
private System.Windows.Forms.ToolStripProgressBar toolStripProgressBar1;
This can be achieved with the default table layout for the statusStrip by simply putting another label between your current label and your progressBar and set the Spring property to true.
Did you tried the Alignment property of ProgresBarToolStripItem set to the Right?
Open your Designer and set
this.toolStripStatusLabel1.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right;

Categories

Resources