How can I keep two Winforms labels centrally aligned? - c#

I'm trying to keep two labels centrally aligned, one above the other. Before the form runs, everything looks great, but when running they are all misaligned.
Before running:
After running:
Example code for one label:
Me.TemperatureLabel1.AutoSize = True
Me.TemperatureLabel1.BackColor = System.Drawing.Color.WhiteSmoke
Me.TemperatureLabel1.Font = New System.Drawing.Font("Bahnschrift", 25.0!)
Me.TemperatureLabel1.ForeColor = System.Drawing.Color.Gray
Me.TemperatureLabel1.Location = New System.Drawing.Point(278, 53)
Me.TemperatureLabel1.Name = "TemperatureLabel1"
Me.TemperatureLabel1.Size = New System.Drawing.Size(227, 41)
Me.TemperatureLabel1.TabIndex = 8
Me.TemperatureLabel1.Text = "TempLabelVal"
Me.TemperatureLabel1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter
Me.TemperatureLabel1.Visible = False
So what I would like is to have the values populated, but centrally aligned above each other.

Set label's AutoSize property to false and TextAlign property to MiddleCenter.

As another option, you can use TableLayoutPanel having 4 columns and 2 rows. Then drop labels inside cells, set Anchor property of the Label controls to none and keep their AutoSize as true.
This way, the labels are always will be aligned in center of the cell.
It also allows you to have absolute, percent or auto-size mode for columns.

Related

Setting the DataGridView AllowUserToResizeColumns is not 100% correct

If I set a the DataGridView to:
dataGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill
dataGridView.AllowUserToAddRows = false;
dataGridView.AllowUserToResizeColumns = false;
And then set my columns like this:
dataGridView.Columns["Colour"].FillWeight = 50;
dataGridView.Columns["Layer"].FillWeight = 50;
cboColumn.DefaultCellStyle.Padding = new Padding(16, 0, 16, 0);
It initially looks great:
I purposely put the mouse over the column resize and it won't allow. Good! But ...
I can still resize the column on the left, and when I do that, my painting on the right looks bad:
So I have two issues here:
Why is it that I can still resize the first column? I don't want to allow it.
If it must be allowed, can we deal with the last column issue?
Thoughts?
To have fixed row header width and prevent users from resizing row header width, you can set RowHeadersWidthSizeMode property of your grid to DisableResizing using designer or code:
grid.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.DisableResizing;
This way the size of row headers would be the fixed value which you set using RowHeadersWidth property of your data grid view control.
You can also use auto size options of DataGridViewRowHeadersWidthSizeMode enumeration.
By default, users can resize the width of the row headers. You can
disable this ability to set a fixed width, or you can use a
content-based automatic sizing mode, which also disables user
resizing.

Determine Control's 'AutoSize'-size at runtime

I want to layout controls during runtime (dynamically created). For the purpose of this question, let's restrict to a Button control. I want to set the control's properties (such as Text) and then determine the minimum size for the control for it to display properly; the size that setting AutoSize = true would give. In C# example code, with GetAutoSizeSize being this minimum size:
Button button = new Button();
this.Controls.Add(button);
button.Text = "Example";
button.Size = GetAutoSizeSize(button);
button.Location = /* Some calculation based on button.Size */
Possible solution: AutoSize
One can set button.AutoSize = true and button.AutoSizeMode = AutoSizeNode.GrowAndShrink. After that, the button.Size can be fetched, after which AutoSize can be turned off and the control size can be changed.
Potential issues:
It looks odd and I can't help but feel that this could easily break, but maybe I am wrong?
Possible solution: GetPreferredSize
button.GetPreferredSize can be used to get a size that the control wants to be.
Problems with this:
Its usage is internal and/or meant for flow layout.
GetPreferredSize takes a suggested size as a parameter, so one needs to guess at what would be appropriate.
The size returned is wrong, in that it returns the 'comfy' size of a control, which can be much larger than the minimum size that AutoSize gives.
EDIT: From the comments and some trial-and-error, I was able to conclude that the problems I originally listed with the AutoSize-method were due to needing both the control to be added to the control collection first and AutoSizeMode set to GrowAndShrink.
I would like to know if there is a function (and/or more 'robust' way) of determining the AutoSize-size: a function like GetPreferredSize that returns the size without actually having to toggle AutoSize.
This works when you are drawing on a control.
String sMyString = "this is my string";
Font fntFont = new Font("Arial", 8);
SizeF sfMySize = new SizeF(5,5);
sfMySize = System.Graphics.MeasureString(sMyString, fntFont, sfMySize);
This will give you the dimensions of the bounding box around the control text. You would have to work out the appropriate buffer around the text to set the button size.

GroupBox autosize

Take a GroupBox, put let say Label inside and then set AutoSizeMode = GrowAndShrink and AutoSize = true.
Two problems will arise:
There is a huge gap between Label and bottom of GroupBox (almost enough to fit another Label lol);
AutoSize doesn't respect the GroupBox.Text property.
Question is how to make GroupBox.AutoSize working properly? Properly means: minimum Width should be enough to fit GroupBox.Text, there should be no gaps below for unknown reason (it's not Margin, nor Padding and it looks pretty ugly).
I've tried to measure string length in OnPaint and setting MinimumSize right there. It works, but I have doubts about this, as if I would want to actually set MinimumSize later - it will be lost after repaint.
Update, here is screenshot:
You can get rid of the unwanted yellow space at the bottom by deriving a new class from GroupBox that adjusts the bottom edge a bit. In VB something like ...
Public Class BetterGroupBox
Inherits GroupBox
Public Overrides Function GetPreferredSize(ByVal proposedSize As Size) As Size
Dim ns = MyBase.GetPreferredSize(proposedSize)
Return New Size(ns.Width, ns.Height - 15)
End Function
End Class
It's simple that the location of your Label is fixed at some point other than (0,0), try this:
label1.Location = Point.Empty;
You may also want to try setting the Padding of your GroupBox to 0 for all (default is 3):
groupBox1.Padding = new Padding(0);
It seems as though the GroupBox control has a predefined padding of sorts when growing the control if AutoSize = true. That is, once a control (inside the GroupBox) gets within 20 pixels or so of the bottom of the GroupBox, the GroupBox starts growing. This causes a 20 pixel or so padding from the bottom of the bottom-most control to the bottom of the GroupBox (as highlighted in yellow by #Sinatr's attached image).
Based on my observations, the padding seems to be less when growing the Width of the GroupBox.
At any rate, you can do something like the following "get around" the issue:
public void MyFunction()
{
groupBox1.AutoSize = true;
// Do stuff (e.g., add controls to GroupBox)...
// Once all controls have been added to the GroupBox...
groupBox1.AutoSize = false;
// Add optional padding here if desired.
groupBox1.Height = myBottomMostControl.Bottom;
}

Row Autosize property not working of Table Layout?

I am working on a windows application, in which i am using a table layout panel, in this table layout i have created 5 rows and that is autosize, now dynamically i am adding 4 radio buttons and text for radio button is a bit long but the problem is it is behaving like absolute and not showing the full text.
I am adding radio button like this-
for (int i = 0; i < 4; i++)
{
rbtn1 = new RadioButton();
rbtn1.Name = "rbtn" + (i + 1);
rbtn1.Text = "A jogger running at 9 kmph alongside a railway track in 280 metres ahead of the engine of a 120 metres long train running at 45 kmph in the same direction. In how much time will the train pass the jogger?";//ansList[i].ToString();
rbtn1.Dock = DockStyle.Fill;
rbtn1.Font = new Font("Verdana", 10);
tableLayoutExamPanel.Controls.Add(rbtn1, 1, i + 8);
}
I am working on this from last 10 hours.
Need help, Thanks a lot.
I realise this is an old question, however:
Set the dock style of each RadioButton to DockStyle.None
Set AutoSize = True for each RadioButton.
Autosize won't work if you have a dock style set. Make sure you the above is true for each child control on the table.
Try setting the radio buttons autosize property to true.
And remember that a control in a TableLayoutPanel cell always shrinks to fit in the cell until its MinimumSize is reached.
P.S. You could also try setting the AutoSizeMode property to GrowOnly.
See MSDN for more info
EDIT: try this...
.RowStyles.Clear();
.RowStyles.Add(new RowStyle(SizeType.AutoSize));

How to resize a button depending on its text

In the process of translating an application with C# + Winforms, I need to change a button's text depending on the language.
My problem is the following :
Let's say I want to translate a button from "Hi all!" to "Bonjour tout le monde" !
As you can guess, the button's size won't be the same if I enter english text or french one... My question is "simple", how can I manage to resize the button on the fly so the text fits its content in the button ?
So far I got something like that !
[Hi all!]
[Bonjour]
There's absolutely no need to use the underlying Graphics object as the other posters have said.
If you set the button's AutoSize property to true, the AutoSizeMode to GrowAndShrink, and the AutoEllipsis to false, it will resize automatically to fit the text.
That being said, you may need to make several layout adjustments to make this change fit into your UI. You can adjust the button's padding to add space around the text, and you may want to place your buttons in a TableLayoutPanel (or something) to stop them from overlapping when they resize.
Edit:
#mastro pointed out that: AutoEllipsis is only valid when AutoSize is false (As explained in the documentation), so it can be safely ignored as long as the other three properties are set correctly.
Your best bet is to set the AutoSize property as described ach's answer
However if AutoSize isn't working for you, resizing the button in code is easy enough. You can just need to set the button's width. The trick is making it big enough to fit your text.
using(Graphics cg = this.CreateGraphics())
{
SizeF size = cg.MeasureString("Please excuse my dear aunt sally",this.button1.Font);
// size.Width+= 3; //add some padding .net v1.1 and 1.0 only
this.button1.Padding = 3;
this.button1.Width = (int)size.Width;
this.button1.Text = "Please excuse my dear aunt sally";
}
Try this:
Button.AutoSize = true;
Button.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowOnly;
Button.TextAlign = ContentAlignment.MiddleLeft;
Button.Padding = new Padding(0, 0, 0, 0);
To enable a Button in WinForms grow and/or shrink depending on the size of the Text, you need to set the button's AutoSize property to True and the AutoSizeMode property to GrowAndShrink.
// C#
btn.AutoSize = true;
btn.AutoSizeMode = AutoSizeMode.GrowAndShrink;
' VB.NET
btn.AutoSize = True
btn.AutoSizeMode = AutoSizeMode.GrowAndShrink
Please note that the AutoSize property will only allow the button's size to grow if the AutoSizeMode property is set to GrowOnly; by changing the AutoSizeMode property to GrowAndShrink, the button will now automatically extend or reduce in width and height based on its Text property.
Also note that in setting the two properties as shown above, you can make use of new lines (Environment.NewLine or vbCrLf) in the Text property and the button will scale down as needed.
As Andrew Hanlon explains, you can set AutoSize = true.
When doing so, you can also attain a perfect layout of the buttons automatically by placing them on a FlowLayoutPanel.
The horizontal distance between them will always stay the same when the FlowDirection of the FlowLayoutPanel is LeftToRight or RightToLeft. You can adjust this distance by setting the Margin property of the buttons appropriately. You can create groups of buttons by increasing the left margin of buttons beginning a new group.
If you set the Dock property of the buttons to DockStyle.Fill, they will even grow their width automatically in order to fit to the widest button if the FlowDirection of the FlowLayoutPanel is TopDown or BottomUp.
btn.AutoSizeMode = AutoSizeMode.GrowOnly;
btn.AutoSize = true;
btn.Dock = DockStyle.Fill;
In addition to setting the AutoSize to true and the AutoSizeModeto GrowAndShrink, as suggested in the other answers, you may also need to set the TextImageRelation property, if you have set the button image, so that the text doesn't overlap the image.

Categories

Resources