开发者

Right-aligned labels in WinForms

The most obvious way to开发者_JAVA技巧 right-align a Label in WinForms doesn't work: setting anchor to Top/Bottom Right and TextAlign to TopRight. If the text changes the label's Left coordinate remains unchanged instead of the Right coordinate (which, one might argue, is a bug).

For this reason I've always used a full-width TableLayoutPanel for right-aligned labels. However this is not always very convenient, depending on the layout in question...

So, I wonder if there are any other ways to keep a Label right-aligned in WinForms that never occurred to me?


One simple option is to disable AutoSize (set to false) and over-size it so there is spare space.

Alternatively, perhaps use Dock instead of just Anchor, although this has a different meaning, so you may need to put it in a Panel or similar). Ultimately this works like the first - by over-sizing it in the first place; so perhaps the first option is simpler.


Using a TableLayoutPanel with docked labels is the only reliable method that I've found for placing right-aligned labels in Winforms. Turning off AutoSize and using oversized labels seems to cause strange anomalies for High DPI users.


Using a FlowLayoutPanel to do it works very well.

flowLayoutPanel.FlowDirection = System.Windows.Forms.FlowDirection.RightToLeft;
flowLayoutPanel2.Controls.Add(label);

Then, just make sure that the flowLayoutPanel is large enough for the label to expand.


Here's what worked for me on a standard form

  • Set AutoSize property off for just the Labels to be right aligned
  • Make all the fields the same size (perhaps this isn't really required) using the Layout toolbar
  • Multi-select the labels and right align them using the Layout toolbar, position where desired
  • Set TextAlign property to one of the xxxRight settings, e.g, TopRight


Well as Sphax noticed you have to:

  1. Set AutoSize to false
  2. Set TextAlign to Right, for example to MiddleRight
  3. Resize label to real size using MeasureString

Code:

label.AutoSize = false; 
label.TextAlign = ContentAlignment.MiddleRight;    

int yourWidthHere = 100;    
using (Graphics g = label.CreateGraphics())    
{    
     SizeF size = g.MeasureString(text, label.Font, yourWidthHere);    
     label.Height = (int)Math.Ceiling(size.Height);    
     label.Text = text;    
}   


  • dynamically created label's default autosize is false.
  • if label's autosize is false. it contains extra empty space.
  • that tricks you to think its doesnt right align properly. to diagnose it, set the label's backColour to lightgreen

Right-aligned labels in WinForms

 int rowIndex=1;

 var lbx = new Label();
 lbx.AutoSize = true;          // default is false.
 lbx.BackColor = Color.Green;  // to see if it's aligning or not
 lbx.Text = "Iam  Autosize=true";
 lbx.Anchor = AnchorStyles.Right;
 tlPanel.Controls.Add(lbx, 0, rowIndex);

 var dtp = new DateTimePicker();
 dtp.Anchor = AnchorStyles.Left;
 tlPanel.Controls.Add(dtp, 1, rowIndex);


  //--- row 2  autosize false
 rowIndex=2;
  var lbx2 = new Label();
 lbx2.AutoSize = false;          // default is false.
 lbx2.BackColor = Color.Green;  // to see if it's aligning or not
 lbx2.Text = "AutoSz=false";
 lbx2.Anchor = AnchorStyles.Right;
 tlPanel.Controls.Add(lbx2, 0, rowIndex);

 var dtp = new DateTimePicker();
 dtp.Anchor = AnchorStyles.Left;
 tlPanel.Controls.Add(dtp, 1, rowIndex);


Here's an approach that hasn't been mentioned yet.

I worked around a similar issue by not using a Label at all. Instead, you can use a TextBox.

On the TextBox, set the following properties:

BorderStyle = None
BackColor = the color of your form
TextAlign = Right

To suppress any visible cursor or user interaction, add a handler for the Enter event. In there, find another control (could be a hidden label), and call Focus on that:

private void txtFakeLabel_Enter(object sender, EventArgs e)
{
    lblHidden.Focus();
}

This responds very nicely to changing the 'label' text dynamically, as long as you make the control wide enough for the text that will appear there.


When adding a control progrmatically, I found it helped to give it a starting location near the location you're trying to anchor it to.

The code below anchors a label to the bottom right of the parent control. It was anchoring to the top left until I added the lblPagename.Location line specifying a location currently near the bottom right. Now when I resize, it stays anchored toward the bottom right (maintaining the padding set below).

int intLabelWidth = 250;
int intLabelHeight = 20;
int intPadding = 20;

Label lblPagename = new Label();
lblPagename.Name = "lblPageName";
lblPagename.Text = "Page Name";
lblPagename.Font = new Font("Segoe UI", 8F, System.Drawing.GraphicsUnit.Point);
lblPagename.AutoSize = false;
lblPagename.Size = new Size(intLabelWidth, intLabelHeight);
lblPagename.TextAlign = ContentAlignment.BottomRight;
lblPagename.Location = new Point(ctl.Width - intLabelWidth - intPadding, ctl.Height - intLabelHeight - (intPadding * 2));
lblPagename.Anchor = (AnchorStyles.Bottom | AnchorStyles.Right);
prnt.Controls.Add(lblPagename);


if you set the form property RightToLeft = yes; so you should not use the Text Align property just set the Anchor. try this approaches:

Form.righttoleft = yes;
label.anchor = Top, Right;
label.TextAlign = TopLeft;

or

Form.righttoleft = No;
label.anchor = Top, Right;
label.TextAlign = TopRight;

or

Form.righttoleft = yes;
label.righttoleft = No;
label.anchor = Top, Right;
label.TextAlign = TopRight;


The best solution for me was:

  1. Set the AutoSize property labels to false. Set the TextAlign
  2. property labels to something on the right.
  3. Resize manually the labels 1 by 1 so they can use more space.


Attach an event handler to the labels' SizeChanged event:

private void label1_SizeChanged(object sender, EventArgs e)
{
    label1.Location = new Point(Your_Anchor_Point - label1.Width, label1.Location.Y);
}

To be more DPI friendly consider using some other control as the anchor point, i.e.

label1.Location = new Point(dataGridView1.Location.X + dataGridView1.Width - label1.Width, label1.Location.Y);

to align to the RH side of the dgv.

(BTW: I tried the Paint & TextChanged events but they seemed to sometimes get confused - probably something to do with event order particularly on opening a new form.)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜