I have a label on my form which is on the right of the form. This label loads a dynamic text.
Sometimes the text that it loads is too long and the text crosses the border of the form, that is some of the text is out of the form.
I want to make the label to grow from right to left instead of left to right. How do I achieve this?
I solved this by setting the label
AutoSize property to false,
TextAlign to MiddleRight,
an Anchor to the right.
Notice that the label size itself is not growing with the text, but you can handle it by giving it enough width to fit the content. The visual effect is the same.
My problem here was that my label was in a panel, and anything I did wasn't working.
What I did was to place the label in a TableLayoutPanel control and set the TableLayoutPanel's RightToLeft property to True; this did the trick.
You can't make it "grow from right to left", but you can assign it's Left property so that it won't go out of the form:
label1.Text = "some dynamic text here...";
if (label1.Right > this.Width)
label1.Left = this.Width - label1.Width;
If the design allows it, you can also double its height so that the text will span two lines.
You can use the TableLayoutPanel or other compatible container control, but instead setting RightToLeft property for the container set Dock="Right" for the label
Setting RightToLeft property does not always give the expected results as for some string formats the string is modified changing the order of the words.
you can Write it:
public enum Leftorright { left,right}
private Leftorright _LeftToRight = Leftorright.left;
public Leftorright LeftToRight
{
get { return _LeftToRight; }
set { _LeftToRight = value; }
}
protected override void OnTextChanged(EventArgs e)
{
int oldWidth;
oldWidth = this.Width;
base.OnTextChanged(e);
if (LeftToRight == Leftorright.right && this.Width != oldWidth)
{
this.Left = this.Left - this.Width + oldWidth;
}
}
using System.Windows.Forms;
/// <summary>
/// The position of myLabel to the left of the otherControl component when entering
/// text "s".
/// You must set myLabel.AutoSize = true
/// </summary>
/// <param name="s">text</param>
void WriteText(string s)
{
int len = TextRenderer.MeasureText ( s, myLabel.Font ).Width;
myLabel.Left = otherControl.Left - 5 - len;
myLabel.Text = s;
}
Wrap the label inside a FlowLayoutPanel and set the following properties in the panel:
Anchor to right;
AutoSize to GrowAndShrink;
FlowDirection to RightToLeft
Related
I have a Control that ultimately inherits from TextBox
If I don't remove the border then the text vertical alignment is fine:
But I want to remove the border like this:
public partial class MyReadonlyDataField : TextBox
{
private void InitializeComponent()
{
this.BorderStyle = System.Windows.Forms.BorderStyle.None;
this.Appearance.BorderAlpha = Infragistics.Win.Alpha.Transparent;
this.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
this.Height = 19;
}
}
But then the text alignment is off. How can I fix that?
I solved it. If I set the perfect height for my TextBox control then the text will be centered, because the control has the exact height that matches the text font.
To achieve that I set the hidden AutoSize property of TextBox. It can't be set in the Forms-Designer nor does IntelliSense list it as property. But it exists and works when set to true!
I am using a group box and there are several controls inside this.
My requirement is to set the group box title to the middle of the group box instead of Left.
How?
you can extend the group box class like this.
public class CustomGrpBox : GroupBox
{
private string _Text = "";
public CustomGrpBox()
{
//set the base text to empty
//base class will draw empty string
//in such way we see only text what we draw
base.Text = "";
}
//create a new property a
[Browsable(true)]
[Category("Appearance")]
[DefaultValue("GroupBoxText")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public new string Text
{
get
{
return _Text;
}
set
{
_Text = value;
this.Invalidate();
}
}
protected override void OnPaint(PaintEventArgs e)
{
//first let the base class to draw the control
base.OnPaint(e);
//create a brush with fore color
SolidBrush colorBrush = new SolidBrush(this.ForeColor);
//create a brush with back color
var backColor = new SolidBrush(this.BackColor);
//measure the text size
var size = TextRenderer.MeasureText(this.Text, this.Font);
// evaluate the postiong of text from left;
int left = (this.Width - size.Width) / 2;
//draw a fill rectangle in order to remove the border
e.Graphics.FillRectangle(backColor, new Rectangle(left, 0, size.Width, size.Height));
//draw the text Now
e.Graphics.DrawString(this.Text, this.Font, colorBrush, new PointF(left, 0));
}
}
add the above class into your project and use "CustomGrpBox" instead of "GroupBox" which will be created after build in your tool box.
and you can set the text any time like this.
private void Form2_Load(object sender, EventArgs e)
{
customGrpBox1.Text = "Hello World";
}
it will look like this in design time visual studio
Unfortunately, you may set the title on the right by using the RightToLeft property, but there is no property to set it in the middle.
What you can do is to set an empty Text in your GroupBox, create a Label with the title and put that label above the GroupBox (with the same parent).
You may do it dynamically at form initialization by calling following procedure:
private void CenterGroupBoxTitle(GroupBox groupbox)
{
Label label = new Label() ;
label.Text = groupbox.Text ;
groupbox.Text = "" ;
label.Left = groupbox.Left+(groupbox.Width-label.Width)/2 ;
label.Top = groupbox.Top + 2 ; // 2 is an example : adjust the constant
label.Parent = groupbox.Parent ;
label.BringToFront() ;
}
Try to create a custom control using Panel as container and draw border around this, you can then have full control of the title's alignment.
If you would like a simple approach, you can leave the groupbox's title as empty text, and then place a label at the center position of the groupbox. You can also define this as user-control so you wouldn't need to do this repeatedly.
Not an eloquent solution, but if you have a simple GroupBox, that stays the( same size, you can just pad the beginning, and the end with spaces.
example : GroupBox.Text = " This is the groupbox text ";
The amount of padding of space's will depend on the length of the box.
Of course you'll lose some of the GroupBox's beginning and end lines on top, and if that's important, then Answer 3 seems like a good solution.
This question already has answers here:
Word wrap for a label in Windows Forms
(20 answers)
Closed 9 years ago.
Is there a way to do a word wrap in a .NET label control?
I know there is an alternate way of using a TextBox, make property BorderStyle to none, property ReadOnly to true and set property WordWrap and property Multiline to true.
Is there something for a label?
Change your maximum size,
label1.MaximumSize = new Size(100, 0);
And set your autosize to true.
label1.AutoSize = true;
That's it!
Just set Label AutoSize property to False. Then the text will be wrapped and you can re-size the control manually to show the text.
Refer to Automatically Wrap Text in Label. It describes how to create your own growing label.
Here is the full source taken from the above reference:
using System;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
public class GrowLabel : Label {
private bool mGrowing;
public GrowLabel() {
this.AutoSize = false;
}
private void resizeLabel() {
if (mGrowing) return;
try {
mGrowing = true;
Size sz = new Size(this.Width, Int32.MaxValue);
sz = TextRenderer.MeasureText(this.Text, this.Font, sz, TextFormatFlags.WordBreak);
this.Height = sz.Height;
}
finally {
mGrowing = false;
}
}
protected override void OnTextChanged(EventArgs e) {
base.OnTextChanged(e);
resizeLabel();
}
protected override void OnFontChanged(EventArgs e) {
base.OnFontChanged(e);
resizeLabel();
}
protected override void OnSizeChanged(EventArgs e) {
base.OnSizeChanged(e);
resizeLabel();
}
}
Ironically, turning off AutoSize by setting it to false allowed me to get the label control dimensions to size it both vertically and horizontally which effectively allows word-wrapping to occur.
If you open the dropdown for the Text property in Visual Studio, you can use the enter key to split lines. This will obviously only work for static text unless you know the maximum dimensions of dynamic text.
If you want some dynamic sizing in conjunction with a word-wrapping label you can do the following:
Put the label inside a panel
Handle the ClientSizeChanged event for the panel, making the
label fill the space:
private void Panel2_ClientSizeChanged(object sender, EventArgs e)
{
label1.MaximumSize = new Size((sender as Control).ClientSize.Width - label1.Left, 10000);
}
Set Auto-Size for the label to true
Set Dock for the label to Fill
You can use a TextBox and set multiline to true and canEdit to false .
I have a Panel with a Label inside.
Sometimes, the Label is very long and the panel must be resized.
I have set the Autosize property to true for both controls, but ....
Can you help me please ?
You also must set AutoSize to true for the containing containers as well, up to the window.
My last attempt in doing so involved quite a bit of redesigning the form with TableLayoutPanel and the like since Dock/Anchor and AutoSize don't seem to mix well.
I have set the Autosize property to true for both controls, but ....
I can tell from the "but" what you are asking for. That's the AutoEllipsis property of the Label. Set it to true and set the MaximumSize property so the label cannot get bigger than its container. The user will see ... so she'll realize the text is truncated. She'll hover the mouse over the label to get a tooltip with the full text.
Letting everything grow to accommodate a label is drastically impractical. You typically can manipulate MaximumSize to let it grow vertically for a while, up to a point.
I encountered a similar problem, and here is a code for you. Assuming your Panel is anchored to the form (top,left,bottom,right), it is the form that needs to be resized, not the Panel.
public static void FitPanel(Panel pnl)
{
int maxright = 0;
int maxbottom = 0;
foreach (Control ctl in pnl.Controls)
{
maxright = (ctl.Right > maxright ? ctl.Right : maxright);
maxbottom = (ctl.Bottom > maxbottom ? ctl.Bottom : maxbottom);
}
int deltabottom = pnl.Bottom - (pnl.Top + maxbottom);
int deltaright = pnl.Right - (pnl.Left + maxright);
Form frm = pnl.FindForm();
frm.SuspendLayout();
frm.Height = frm.Height - deltabottom;
frm.Width = frm.Width - deltaright;
frm.ResumeLayout();
}
I need some code to convert standard C# TextBox to temperature TextBox which means adding "°C" to end of the text in the textbox with another color than the default color.
To get the degree symbol you can use character code 176 e.g.
Char degree = (Char)176
You can then append this to your textbox content or I would just add a label to the right of the textbox with the degree symbol if you want to control the forecolor easily.
TextBox is a plain text editor. To get different colours you would have to muck around with a rich text box. Why not put the "°C" in a label positioned to the right of the text box? That would also make your parsing and rendering code much easier.
You could probably create your own control which inherits from TextBox and then override Text property to automaticaly add °C though other color inside the same TextBox could be problem.
Why you want to have °C in TextBox ?
Can't it just be label right after TextBox ?
You can set static text and color to what you want.
The other solutions proposed here are probably sufficient for your application; however, if you had the need to implement this with re-usability in mind, here is a custom control solution which you may extend to better suit your application:
public class TemperatureTextBox : ContainerControl
{
private const int BORDER_SIZE = 1;
// Exposes text property of text box,
// expose other text box properties as needed:
public override string Text
{
get { return textBox.Text; }
set { textBox.Text = value; }
}
private TextBox textBox = new TextBox()
{
Text = string.Empty,
BorderStyle = BorderStyle.None,
Dock = DockStyle.Fill
};
private Label label = new Label()
{
Text = "°C",
TextAlign = ContentAlignment.MiddleCenter,
Size = new Size()
{
Width = 32
},
BackColor = SystemColors.Window,
Dock = DockStyle.Right
};
public TemperatureTextBox()
{
this.BackColor = SystemColors.Window;
this.Padding = new Padding(BORDER_SIZE);
this.Controls.Add(label);
this.Controls.Add(textBox);
this.PerformLayout();
}
// Constrain control size to textbox height plus top and bottom border:
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
this.Height = (textBox.Height + (BORDER_SIZE * 2));
}
// Render a border around the control:
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
e.Graphics.DrawRectangle(
SystemPens.ControlDarkDark,
new Rectangle()
{
Width = (this.Width - BORDER_SIZE),
Height = (this.Height - BORDER_SIZE)
});
}
}
Simply create a new class and drop this code in and rebuild you solution. It will create a new TemperatureTextBox control in the toolbox which can be dropped onto a new form and visually designed.
This example exposes the Text property of the underlying text box by overriding the custom control's text property. You may want to expose other properties, and events depending on what your application needs to accomplish.