I want a box of a fixed size to show some text and have a link in it that is clickable in the bottom right corner for editing. Clicking this edit link shows a set of fields to fill in.
I tried LinkLabel, which does the trick, but, when I change the text, the size of the box changes. I set autosize to false and longer text forces the link outside the box. Short text puts the link to far up.
I could get fancy and calculate the position of the link and insert it at the appropriate place (adding new lines if needed), but I'm wondering if there isn't an easier way to do this.
Is there a better control for doing this or another way of doing this?
EDIT:
The boxes that are filled in are concatenated and replace the text in the linklabel. The Edit link is currently appended to this and a LinkArea (of the last 4 characters) is set.
You need to build a composite layout, for instance using a Panel with Label/TextBox (Dock = Fill) and LinkLabel (Dock = Bottom, TextAlign = MiddleRight) inside, like this
using System;
using System.Drawing;
using System.Windows.Forms;
namespace Samples
{
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var text = "I want a box of a fixed size to show some text and have a link in it that is clickable in the bottom right corner for editing.";
int textSize = 50;
var form = new Form { Padding = new Padding(8) };
var panel = new Panel { Parent = form, BorderStyle = BorderStyle.FixedSingle, Padding = new Padding(4) };
var label = new Label { Dock = DockStyle.Fill, Parent = panel, AutoSize = false, Text = text, Height = textSize };
var link = new LinkLabel { Dock = DockStyle.Bottom, Parent = panel, AutoSize = false, TextAlign = ContentAlignment.MiddleRight, Text = "Edit" };
panel.Location = form.DisplayRectangle.Location;
panel.Width = form.DisplayRectangle.Width;
panel.Height = panel.Padding.Vertical + link.Height + label.Height;
Application.Run(form);
}
}
}
Result:
I found another way.
I use a text box and position a linklabel in its corner.
textbox is readonly and disabled so it acts like a label and the backcolor is set to white to over-ride the disabled/readonly colour.
The edit link now stays put
I am creating a custom control, a custom looking TextBox designed to only allow numeric input. It consists of a plain control, with a TextBox as one of it's properties:
class NumericControl : Control
{
private TextBox text;
//rest of the code
}
This TextBox is drawn inside of the control. It all works very nicely, except that when you press enter it makes this horrible DING noise. To fix this, I thought I'd make the TextBox multiline. However, when I do this, because the font size of the TextBox is changed to resize it, the blinking cursor inside the TextBox appears to disappear, which is a problem because then you can't tell by looking at it whether or not it has focus. If I don't change the font size of the TextBox, the cursor appears and acts normally, however I need the font size to change based on the height of the control, otherwise it doesn't look any good.
The code setting the TextBox properties is as follows, and resides within the constructor of my control:
text = new TextBox();
text.AutoSize = false;
text.Left = 10;
text.Top = 2;
text.Text = "0";
text.Multiline = true;
text.BorderStyle = BorderStyle.None;
text.TextChanged += text_TextChanged;
text.LostFocus += text_LostFocus;
this.Controls.Add(text);
The font size is changed inside the OnPaint event, and looks like this:
text.BackColor = Enabled ? Background : SystemColors.Control; //Fixes an issue I had with disabled TextBox BackColor being able to be changed
text.Font = new Font(TextBox.DefaultFont.FontFamily, (float)(rc.Height * 0.7 - 2), FontStyle.Regular);
text.Width = this.Width - 21;
text.Height = this.Height - 4;
How do I both resize the textbox (and font size), and make it multiline while retaining the blinking cursor when it has focus?
I created some labels in a for loop on the behind code.
At the beginning it looks like that:
private void SlotLabelCreation(string name)
{
Label label = new Label();
label.Name = name;
label.HorizontalAlignment = HorizontalAlignment.Left;
label.VerticalAlignment = VerticalAlignment.Top;
label.Content = "[Free Slot]";
label.Foreground = Brushes.Gray;
label.BorderBrush = Brushes.Black;
label.BorderThickness = new Thickness(1);
label.Visibility = Visibility.Hidden;
MainGrid.Children.Add(label);
//the margin has been inserted later in other code.
}
everything was fine but when I inserted to the label other content which not contains the same amount of letters it looks like that:
sorry about the links.. it's because I can't upload images
http://s27.postimg.org/6halp6p37/pic2.png
I wanted to make all slots the same size so I added a MinWidth property to the labels.
The new result was:
http://s27.postimg.org/6z5r51eo3/pic3.png
now it looks better but I am wondering how could I center the content which inside the label.
Unfortunately I didn't find any solution to solve this problem.
p.s, HorizontalAlignment and VerticalAlignment don't solve the problem.
Thanks a lot, Alon P.
You should use HorizontalContentAlignment and VerticalContentAlignment properties
I have a simple Windows Forms application with a tabControl. I have 3 panels on the tabControl, each having 5 buttons. The text on first set of buttons is hard-coded, but the next set populates when you click one from the first group, and then the same thing happens again for the last group when you click one of the buttons from the second group. In the [Design] view I manually set the TextAlign property of each button to MiddleCenter. However, when I run the application the text on the middle set of buttons is never centered. It is always TopLeft aligned. I've tried changing the font size and even explicitly setting the TextAlign property every time I set button text programmatically, as follows:
private void setButtons(List<string> labels, Button[] buttons)
{
for (int i = 0; i < buttons.Count(); i++)
{
if (i < labels.Count)
{
buttons[i].Text = labels.ElementAt(i);
buttons[i].TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
buttons[i].Enabled = true;
}
else
{
buttons[i].Text = "";
buttons[i].Enabled = false;
}
}
}
This image shows the result:
Does anyone have any ideas for what I'm missing?
Trim text which you are assign to button. Also you can refer label by index, without calling ElementAt
private void setButtons(List<string> labels, Button[] buttons)
{
for (int i = 0; i < buttons.Count(); i++)
{
Button button = buttons[i];
if (i < labels.Count)
{
button.Text = labels[i].Trim(); // trim text here
// button.TextAlign = ContentAlignment.MiddleCenter;
button.Enabled = true;
}
else
{
button.Text = "";
button.Enabled = false;
}
}
}
You can set the UseCompatibleTextRendering property to true, then use the TextAlign property.
The strings in the SQL table that were assigned to the middle column were actually nchar(50), not nvarchar(50), which explains the problem. I added .Trim() to the Text assignment and it looks great now.
You can use the TextAlign from the Properties Menu and set it to MiddleCenter ...
If this does not work then the text you have for your button is larger than the actual button itself... to which you should either rescale your Font Size to a lower base size or a percent size of the actual button by using
btnFunction.Font = new Font(btnFunction.Font.Name, Convert.ToInt32(btnFunction.Height * 0.3333333333333333));
This would cause the button's font to be one third of the height of the button....
How do I change the height of a textbox ?
Neither of the below work:
this.TextBox1.Size = new System.Drawing.Size(173, 100);
or
this.TextBox1.Size.Height = 100;
I wanted to be able to change the single line text box height to fit a font size on it without using multi-line if possible.
Go into yourForm.Designer.cs
Scroll down to your textbox. Example below is for textBox2 object.
Add this
this.textBox2.AutoSize = false;
and set its size to whatever you want
this.textBox2.Size = new System.Drawing.Size(142, 27);
Will work like a charm - without setting multiline to true, but only until you change any option in designer itself (you will have to set these 2 lines again).
I think, this method is still better than multilining. I had a textbox for nickname in my app and with multiline, people sometimes accidentially wrote their names twice, like Thomas\nThomas (you saw only one in actual textbox line). With this solution, text is simply hiding to the left after each char too long for width, so its much safer for users, to put inputs.
There are two ways to do this :
Set the textbox's "multiline" property to true, in this case you don't want to do it so;
Set a bigger font size to the textbox
I believe it is the only ways to do it; the bigger font size should automatically fit with the textbox
You can set the MinimumSize and/or the MaximumSize properties of the textbox. This does not affect the size immediately, but when you resize the textbox in the forms designer, the size will automatically be adjusted to satisfy the minimum/maximum size constraints. This works even when Multiline is set to false and does not depend on the font size.
Just found a great little trick to setting a custom height to a textbox.
In the designer view, set the minimumSize to whatever you desire, and then completely remove the size setting. This will cause the designer to update with the new minimum settings!
set the minimum size property
tb_01.MinimumSize = new Size(500, 300);
This is working for me.
Try the following :)
textBox1.Multiline = true;
textBox1.Height = 100;
textBox1.Width = 173;
Steps:
Set the textboxes to multiline
Change the height
Change the font size. (so it fit into the big textboxes)
Set the textboxes back to non-multiline
public partial class MyTextBox : TextBox
{
[DefaultValue(false)]
[Browsable(true)]
public override bool AutoSize
{
get
{
return base.AutoSize;
}
set
{
base.AutoSize = value;
}
}
public MyTextBox()
{
InitializeComponent();
this.AutoSize = false;
}
}
May be it´s a little late. But you can do this.
txtFoo.Multiline = true;
txtFoo.MinimumSize = new Size(someWith,someHeight);
I solved it that way.
AutoSize, Minimum, Maximum does not give flexibility. Use multiline and handle the enter key event and suppress the keypress. Works great.
textBox1.Multiline = true;
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
e.Handled = true;
e.SuppressKeyPress = true;
}
}
You can put it inside a panel that has the same back color with your desired height. This way has this advantage that the text box can center horizontally, which is not provided by other solutions.
You can make it even more natural by using the following methods
private void textBox1_Enter(object sender, EventArgs e)
{
panelTextBox.BorderStyle = BorderStyle.FixedSingle;
}
private void textBox1_Leave(object sender, EventArgs e)
{
panelTextBox.BorderStyle = BorderStyle.None;
}
The Simplest Way to do that
Right click on the TextBox.
Go to properties.
Set Multiline = True.
Now you will be able to resize the TextBox vertically as you wish.
for me, the best approach is remove border of the textbox, and place it inside a Panel, which can be customized as you like.
The following code added in your constructor after calling InitializeComponent() will make it possible to programmatically set your text box to the correct height without a) changing the Multiline property, b) having to hardcode a height, or c) mucking with the Designer-generated code. It still isn't necessarily as clean or nice as doing it in a custom control, but it's fairly simple and robust:
if (txtbox.BorderStyle == BorderStyle.None)
{
txtbox.BorderStyle = BorderStyle.FixedSingle;
var heightWithBorder = txtbox.ClientRectangle.Height;
txtbox.BorderStyle = BorderStyle.None;
txtbox.AutoSize = false;
txtbox.Height = heightWithBorder;
}
I decided to make it cleaner and easier to use by putting it in a static class and make it an extension method on TextBox:
public static class TextBoxExtensions
{
public static void CorrectHeight(this TextBox txtbox)
{
if (txtbox.BorderStyle == BorderStyle.None)
{
txtbox.BorderStyle = BorderStyle.FixedSingle;
var heightWithBorder = txtbox.ClientRectangle.Height;
txtbox.BorderStyle = BorderStyle.None;
txtbox.AutoSize = false;
txtbox.Height = heightWithBorder;
}
}
}
Some of you were close but changing designer code like that is annoying because you always have to go back and change it again.
The original OP was likely using an older version of .net because version 4 autosizes the textbox height to fit the font, but does not size comboboxes and textboxes the same which is a completely different problem but drew me here.
This is the problem I faced when placing textboxes next to comboboxes on a form. This is a bit irritating because who wants two controls side-by-side with different heights? Or different fonts to force heights? Step it up Microsoft, this should be simple!
I'm using .net framework 4 in VS2012 and the following was the simplest solution for me.
In the form load event (or anywhere as long as fired after InitializeComponent): textbox.AutoSize = false Then set the height to whatever you want. For me I wanted my text boxes and combo boxes to be the same height so textbox.height = combobox.height did the trick for me.
Notes:
1) The designer will not be affected so it will require you to start your project to see the end result, so there may be some trial and error.
2) Align the tops of your comboboxes and textboxes if you want them to be aligned properly after the resize because the textboxes will grow down.
This is what worked nicely for me since all I wanted to do was set the height of the textbox. The property is Read-Only and the property is in the Unit class so you can't just set it. So I just created a new Unit and the constructor lets me set the height, then set the textbox to that unit instead.
Unit height = txtTextBox.Height;
double oldHeight = height.Value;
double newHeight = height.Value + 20; //Added 20 pixels
Unit newHeightUnit = new Unit(newHeight);
txtTextBox.Height = newHeightUnit;
You can make multiline : false and then just change the text size on the text box then the height will automatically increment
you can also change you can also change MinimumSize
So after having the same issue with not being able to adjust height in text box, Width adjustment is fine but height never adjusted with the above suggestions (at least for me), I was finally able to take make it happen. As mentioned above, the issue appeared to be centered around a default font size setting in my text box and the behavior of the text box auto sizing around it. The default font size was tiny. Hence why trying to force the height or even turn off autosizing failed to fix the issue for me.
Set the Font properties to the size of your liking and then height change will kick in around the FONT size, automatically. You can still manually set your text box width. Below is snippet I added that worked for me.
$textBox = New-Object System.Windows.Forms.TextBox
$textBox.Location = New-Object System.Drawing.Point(60,300)
$textBox.Size = New-Object System.Drawing.Size(600,80)
$textBox.Font = New-Object System.Drawing.Font("Times New Roman",18,[System.Drawing.FontStyle]::Regular)
$textBox.Form.Font = $textbox.Font
Please note the Height value in '$textBox.Size = New-Object System.Drawing.Size(600,80)' is being ignored and the FONT size is actually controlling the height of the text box by autosizing around that font size.
All you have to do is enable the multiline in the properties window, put the size you want in that same window and then in your .cs after the InitializeComponent put txtexample.Multiline = false; and so the multiline is not enabled but the size of the txt is as you put it.
InitializeComponent();
txtEmail.Multiline = false;
txtPassword.Multiline = false;
I think this should work.
TextBox1.Height = 100;