How does the size get calculated when using GetPreferredSize()? - c#

I'm using label to display the message. I have calculated the size of the label by using GetPreferredSize() method. This method works fine when I didn't do any manipulation in sizing the label. But when, I reduce the width of the label, the text gets clipped. However, if I include a newline(\n) at the end of the text to be displayed, the text which gets clipped in previous case is displayed in the next line.
Here is what I tried.
label1.Text = "Are you sure you wish to cancel? \n You will permanently discard any information you have entered!";
label1.Font = new Font(new FontFamily("Calibri"), 15);
Size textSize = label1.GetPreferredSize(Size.Empty); //Works fine.
label1.Size = textSize;
textSize.Width -= 25;
label1.Size = textSize;// Text is clipped.
label1.Text = "Are you sure you wish to cancel? \n You will permanently discard any information you have entered! \n "; //Works fine again!
Refer to the image,
Label Text
If the method calculates the size of the label based on the contents, why does the content clipped in case2 and works good in case3? How does the width and height is related to? Can anyone explain what I'm missing?
Thanks,
Sindhu

Size sz = new Size(this.Width, Int32.MaxValue);
sz = TextRenderer.MeasureText(this.Text, this.Font, sz, TextFormatFlags.WordBreak);
this.Height = sz.Height;
where "this " is your control.

How big was text size before decreasing it by 25? Maybe it's just not enough space and cut off - try with a different number. And ... you certainly wanted to subtract and not assign?

Modify the "Anchor" setting to only anchor to the left or the right

Related

C# UWP - Wrong caret size when there is no text

I have a RichEditBox and want to change the font size of the selection. When I don't select anything, and then change the font size, the caret size doesn't get bigger, until I start typing some characters (spaces don't work). When I delete all of those characters, the caret shrinks again, until I type some characters. Is there any possibility to change the caret size immediately, like in programs like Word?
ITextSelection selection = Editor.Document.Selection;
if(selection != null) {
float fontSize;
try {
fontSize = (float) Convert.ToDouble(fontSizeBox.Text);
} catch(FormatException) {
fontSize = 11;
}
selection.CharacterFormat.Size = fontSize;
}
Editor.Focus(FocusState.Programmatic);
You can do this by a trick using PlaceholderText
<RichEditBox PlaceholderText="Input your text" FontSize="52"/>
Update:
Well, I added some screenshot and did the test.
The caret did shrink a little when enter a new line. And it get bigger when RichEditBox changed from palceholder text to your own text.
This is really interesting.
I think this maybe a bug created by Microsoft.
Default:
The first line
Enter a new line

Compress text to fit within a control's displayed width

In my C# WinForms application, I have a control in which I display some text to the user on screen. For time being, assume it is a TextBox.
My requirement is if the text does not fully fit within the displayed width of the control, I want to keep reducing the font size or compress the text in some other way to fit the displayed width of the control.
I understand in extreme situations, the text may not be readable at all. But that's fine.
Can I get a code example how to achieve this?
To measure the width of the font you'll have to determine it using TextRenderer. The following code illustrates how to achieve this, and to resize the font in the textbox.
var text = "Some unnecessarily long, long, long string.";
var size = default(SizeF);
// SizeF size; // Use this if you're on an older version of C# without default
do
{
using (var font = new Font(textBox1.Font.Name, textBox1.Font.SizeInPoints))
{
size = TextRenderer.MeasureText(text, font);
if (size.Width <= textBox1.Width)
textBox1.Text = text;
else
{
textBox1.Text = "Won't fit";
textBox1.Font = new Font(font.Name, font.SizeInPoints - 1f);
}
}
} while (size.Width > textBox1.Width);
You may want to adjust the by how much the font size decreases if it ends up too small for your liking.

how to fit a long text into a UITextView or UILabel

i'm developing an ios app with xamarin.
i need to fit a long text into a content (UILabel or UITextView).
this is the code i used:
var descStrLabel = new UITextView(new CGRect(0, 250, w, 550));
descStrLabel.BackgroundColor = UIColor.Black;
descStrLabel.Font = UIFont.SystemFontOfSize(10.0f);
descStrLabel.TextAlignment = UITextAlignment.Center;
descStrLabel.TextColor = UIColor.LightGray;
descStrLabel.Text = #"HERE THE LONG TEXT...";
//descStrLabel.Lines = 0;
descStrLabel.AutoresizingMask = UIViewAutoresizing.FlexibleWidth;
View.Add(unified);
View.Add(subtitle);
View.Add(descStrLabel);
When i debug the application, the last part of the text is missing...
maybe i need to set the width at runtime...
thanks in advance for your help
I don't really know how you want to "fit" the text. If you want to show the text all in one line, try calling SizeToFit():
desc.SizeToFit();
documentation for SizeToFit():
Moves and resizes the UIView so that it tightly encloses its UIView.Subviews
If you want the UITextView to wrap lines, then you don't need to do anything! Line wrapping is enabled by default. If it doesn't for you, try setting LineBreakMode:
desc.TextContainer.LineBreakMode = UILineBreakMode.WordWrap;
documentation for WordWrap:
Wraps at the first word that does not fit.

WinForms Button: Autosize Maximumsize

I want to add Buttons to a FlowLayoutPanel. The Buttons might contain longer texts with spaces between the words. The Buttons are Autosize=true and AutoSizeMode = AutoSizeMode.GrowAndShrink. Further more I set the MaximumSize property to (maxwidth,0). maxwidth is the width of the panel. So the button does not grow too wide.
What I see is, that the widht of the Button is limited by the MaximumSize property, but when text wrapping occurs, the Button's height doesn't autosize to the height of the wrapped text. Is there a solution to that problem?
I also tried this manually sizing the button like this:
using (Graphics cg = this.CreateGraphics()) {
SizeF size = cg.MeasureString(button.Text, button.Font, 200);
button.Width = (int)size.Width+20;
button.Height = (int)size.Height+20;
button.Text = someLongTextWithSpaces;
}
But please note that I added 20 to the calculated size. It's working, but is there a proper way to determin this additional size? Maybe 2x Padding + ?????
A few hours later...
I came to this version which seems to work quite fine.
using (Graphics cg = this.CreateGraphics()) {
var fmt = TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter | TextFormatFlags.WordBreak;
var prop = new Size(tableLayoutPanel1.Width - 20, 0);
var size = TextRenderer.MeasureText(button.Text, button.Font, prop, fmt);
int border = button.Height - button.Font.Height;
button.Width = (int)size.Width + border;
button.Height = (int)size.Height + border;
button.Text = someLongTextWithSpaces;
}
It seems that the initial button height is borders + the height the font. So I calculated the border subtracting button.Height-button.font.Height.
According to Hans, I now use the TextRenderer.MeasureText. I tested it without enabling VisualStyles and it worked fine. Any comments on that?
There is a proper way, but it isn't exactly very subtle. Reverse-engineering it from the ButtonRenderer class source code, the Winforms class that draws the button text, you must use the TextRenderer class to measure the text. And you must use the VisualStyleRenderer.GetBackgroundContentRectangle() method to obtain the effective drawing bounds. Note that it is smaller than the button's Size because of the border and a margin that depends on the selected visual style.
Non-trivial problems are mapping a calculated content rectangle back to the outer button size and dealing with old machines that don't have visual styles enabled. Sample code that appeared to arrive at the correct size:
private static void SetButtonSize(Graphics gr, Button button) {
VisualStyleElement ButtonElement = VisualStyleElement.Button.PushButton.Normal;
var visualStyleRenderer = new VisualStyleRenderer(ButtonElement.ClassName, ButtonElement.Part, 0);
var bounds = visualStyleRenderer.GetBackgroundContentRectangle(gr, button.Bounds);
var margin = button.Height - bounds.Height;
var fmt = TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter | TextFormatFlags.WordBreak;
var prop = new Size(bounds.Width, 0);
var size = TextRenderer.MeasureText(button.Text, button.Font, prop, fmt);
button.ClientSize = new Size(button.ClientSize.Width, size.Height - margin);
}
protected override void OnLoad(EventArgs e) {
using (var gr = this.CreateGraphics()) {
SetButtonSize(gr, this.button1);
}
base.OnLoad(e);
}
Not extensively tested for corner cases, can't say I recommend this.
It seems that the initial button height is borders + the height the font. So I calculated the border subtracting button.Height-button.font.Height. (See the last block of my original post)
This also works with VisualStyles enabled/disabled.
You should control the line breaks by adding newline characters in the text. Automatic text wrapping won't work with spaces alone:
button1.Text = "123232131232\r\nfgfdgfdgdfgdfgdf\r\nASDSADSDASD";
Or :
button1.Text = "123232131232" + Environment.NewLine +
"fgfdgfdgdfgdfgdf" + Environment.NewLine + "ASDSADSDASD";
If you'd rather get the automatic wrapping you could try to use TextMeasure to determine the height needed for the text and then set the button's height accordingly but that may need some extra attention..
But I suggest to consider using Labels instead. For a Label the wrapping works out of the box.. Huge Buttons with varying sizes are non-standard UI elements.

How can i calculate the distance from the top of pictureBox1 and almost the top of form1?

I have a label with text inside i can change the label size or the label font size each time and check many times but maybe there is a way to calculate it:
label18.Text = "מכם מזג האוויר איננו פעיל כרגע";
This is how i see the text now:
The text in red is in hebrew this is the text i want to change it's size and also to put it in the middle according to the picturebox1 top not on the left like it is now.
And i did a black circle just to show what i mean by " the distance from the top of pictureBox1 and almost the top of form1 ".
I mean this gray area from the above the pictureBox1 and the form1 white area on the top only this gray area i want to make the text in this height and in the middle.
How can i calculate this two values ?
I tried this but it's not in the exact middle:
SizeF size = label18.CreateGraphics().MeasureString(label18.Text, label18.Font);
label18.Left = (pictureBox1.Width / 2) - (((int)size.Width) / 2) + pictureBox1.Left;
label18.Top = pictureBox1.Top - 20;
You don't need graphics or to measure anything. Just set in designer text align = middlecenter and autosize = true
label18.Location = new Point(pictureBox1.Location.X + (pictureBox1.Width / 2 - label18.Width / 2,
pictureBox1.Location.Y - label18.Height);
To center a label you need it get it actual size, then to center it using another control use some simple math to get the coordinate for the control (see below Example 1). I don't know what control the grey bar is but you could center in that by using the size.Width property and doing the same type of calculation.
If you want to fill the grey bar I have added Example 2.
Example 1:
private void CenterLabel()
{
//get the size of the text (you could do this before hand if needed)
SizeF size = label18.CreateGraphics().MeasureString(label18.Text, label18.Font);
//center over picture box control and slightly above
label18.Left = (pictureBox1.Width / 2) - (((int)size.Width) / 2) + pictureBox1.Left;
label18.Top = pictureBox1.Top - 20;
}
Example 2
private void CenterLabel()
{
int fontHeightPixels = (int)(greyBar.Height * .85);
Font font = new System.Drawing.Font("Arial", fontHeightPixels, FontStyle.Regular, GraphicsUnit.Pixel);
string text = "I am centered";
//get the size of the text (you could do this before hand if needed)
SizeF size = label18.CreateGraphics().MeasureString(text, font);
label18.Font = font;
label18.Text = text;
//center over picture box control and slightly above
label18.Left = (pictureBox1.Width / 2) - (((int)size.Width) / 2) + pictureBox1.Left;
label18.Top = (greyBar.Height / 2) - (((int)size.Height) / 2) + greyBar.Top;
}
This is relatively simple with Windows forms:
Dock your label to the top of the form by setting the appropriate property in the Forms designer. The property you want to set is Dock and it should be set to Top.
Change the label's AutoSize property to false.
Change the label's height as desired.
Change the label's TextAlign property to MiddleCentre.
That should do it.
There's more then one way to achieve this goal.
I would suggest the following:
First calculate the width of the picturebox (picturebox.Width)
Find the coordinates on the form where the picturebox resides (picturebox.Location) property of the picturebox)
Then you change the location of your label control --> to Label.Location.X = (picturebox.Width /2) and Label.Location.Y = picturebox.Location.Y ==> now you have the label correctly placed .
Next Set the Height of the Label Control to the Top(distance between the edge of the form and picturebox) value of the Picturebox.
No visual studion from where i am typing so cannot do full code example.
You're done.

Categories