 |
|
 |
stuck......plz help How to get actual height of a textbox before rendering the object
in wpf???????
textBox1.Text = "Test";
FontFamily fontFamily = new FontFamily("Arial");
float FontLineSpacing = fontFamily.GetLineSpacing(FontStyle.Regular);
// Get the em height of the font family in design units.
int emHeight = fontFamily.GetEmHeight(FontStyle.Regular);
var Height = (textBox1.Font.Size * FontLineSpacing / emHeight) + 7;
above code will work in windows but in wpf ???????????????
|
|
|
|
 |
|
 |
The textbox control has an AutoSize property which can be disabled. However, this method will not change the font size - so you will get a great big textbox with an itty-bitty font.
It is a hidden property which will not show up in the IDE, but it will not throw an error if used in code. To set the height of a TextBox by disabling auto-sizing:
textBox1.AutoSize = false;
textBox1.Height = 50;
This Visual Studio Magazine article[^], from which this comment was based, includes a great explanation of the back-end code and how you can access it in VS 2008.
|
|
|
|
 |
|
 |
I'll have to remember this.
There have been a couple of time where that's what I wanted to do with a TextBox, but it never occurred to me to set textBox1.AutoSize = false;
|
|
|
|
 |
|
 |
I've incorporated this technique in with your other ideas I've used in my TextBox control. You may (or may not) be interested:
private int default_Height = -1; [System.ComponentModel.Category("Layout")]
[System.ComponentModel.Description(
"Set the TextBox.Height to a specific value "
+"via disabling of the .AutoSize property."
)]
public int Size_ManualHeight
{
get {return this.Height;}
set
{
if (value != this.Height)
{
if (default_Height <= 0)
{
default_Height = this.Height;
}
if( (value > 0)
&& (value != default_Height) )
{
if (value > default_Height)
{
this.AutoSize = false;
this.Height = value;
}
else
{
this.Font = GetFontForTextBoxHeight(
value,
(this.BorderStyle != System.Windows.Forms.BorderStyle.Fixed3D),
this.Font
);
this.AutoSize = false;
this.Height = value;
}
}
else
if (!this.AutoSize)
{
this.Font = GetFontForTextBoxHeight(
default_Height,
(this.BorderStyle != System.Windows.Forms.BorderStyle.Fixed3D),
this.Font
);
this.Height = default_Height; this.AutoSize = true;
}
}
}
}
[System.ComponentModel.Category("Layout")]
[System.ComponentModel.Description(
"Set the TextBox.Height to a specific value "
+"via manipulation of its .Font properties."
)]
public int Size_AdjustedHeight
{
get {return this.Height;}
set
{
if (value != this.Height)
{
if (default_Height <= 0)
{
default_Height = this.Height;
}
this.Font = GetFontForTextBoxHeight(
value,
false,
this.Font
);
}
}
}
private static System.Drawing.Font GetFontForTextBoxHeight(
int TextBoxHeight,
bool ExtraFontPoints,
System.Drawing.Font OriginalFont
)
{
float desiredoffset = 7f;
if (ExtraFontPoints)
{
desiredoffset = 5f;
}
float emSize = (desiredheight - desiredoffset) * FontEmSize / FontLineSpacing;
}
As part of incorporating this technique, I also made a slight mod to the [GetFontForTextBoxHeight()] method, as shown above. My thought is that if I'm using this technique of disabling of the .AutoSize property to explicitly set the textbox .Height *and* the textbox's .BorderStyle != System.Windows.Forms.BorderStyle.Fixed3D then I can squeeze in a couple more pixels of size for the text. My testing of this idea has worked fine.
edit: On these extra points for the fontsize:
The reason to call the [GetFontForTextBoxHeight()] method in the first place from the [Size_ManualHeight] set accessor when [(value >= default_Height)] is because otherwise the fontsize is too large for the height of the textbox (and the displayed value will probably be clipped). At the same time, if the value set to [Size_ManualHeight] is much less than 15, the text value quickly becomes unreadable. The idea of allowing for 2 extra pixels was a way to somewhat alleviate this. Though, the idea doesn't work out well if the textbox's .BorderStyle == System.Windows.Forms.BorderStyle.Fixed3D
The reason to pass the value 'false' in the call to the [GetFontForTextBoxHeight()] method which made from the [Size_AdjustedHeight] set accessor is, of course, because that logic does not override the [this.AutoSize] property.
|
|
|
|
 |
|
 |
Did you find this formula somewhere in MSDN or reverse-engineered the answer out of somewhere or is it just something you cooked up? I always thought that text box height should be relative to Dialog Base Units if it is used in a dialog. (i.e. it is exactly 8 or so Dialog Base Units)
This article also says how you can get Dialog Base Units for non-system fonts:
http://support.microsoft.com/kb/125681[^]
Please ignore me if this is about a different type of text-box.
I'm gonna hold my vote until I get an answer...
|
|
|
|
 |
|
 |
sk8er_boy287 wrote: I'm gonna hold my vote until I get an answer...
That's certainly better than being an auto-Univoter!
|
|
|
|
 |
|
 |
Let me guess... like whomever uni-voted my question?
"This method will return a font object that will set the size of your text box:"
What does that even mean? You can't set the size of anything using a font.
Wow! I just realized this article is terribly titled and I misinterpreted the whole lot of it! It's about setting Font size, not TextBox size. Well, there goes my uni-vote of the day.
|
|
|
|
 |
|
 |
sk8er_boy287 wrote: What does that even mean? You can't set the size of anything using a font. Hmmm
Try to adjust the height property of a textbox (with multi-line set to false). The height will not change. Now adjust the font size - the height of the textbox changes to accommodate the taller font. Now set it by fractions of pixels - the textbox height will change ever so slightly. The font calculations were to calculate just the right font size to make the textbox increase to the desired height.
The goal of the article is not about setting the font size, it is about changing the height of a cantankerous control that does not give us an obvious way to set the height.
|
|
|
|
 |
|
 |
I don't think you understand what I'm trying to say. The article is titled wrong. What you're doing is calculating font size based on given TextBox size, while the title says the exact opposite.
Also, your method might not always work. Try changing the display DPI setting to something significantly different than the default 96 (you may need to reboot), then see if it still works... The fact that you're using hard-coded constants is a throw-off. I've seen this kind of issues in lots of software, where they ignore the DPI setting and do this kind of wrong calculations...
You can always change the height of a control or any other window, for that matter, from code... I don't know much about C# properties, though, so I might be wrong.
|
|
|
|
 |
|
 |
Actually, DPI settings were taken into account in the calculations by switching the font to GraphicsUnit.Pixel. The Em values remain the same, independent of DPI settings. Where I would have gotten into trouble with DPI settings is if I had retained the GraphicsUnit.Point, where a calculation from point-to-pixel (or inch, or world, or furlongs, for that matter ) would factor in the DPI settings.
I did try it after reading your comment. It does still work, even at 200% DPI, which btw, is quite fugly.
sk8er_boy287 wrote: You can always change the height of a control or any other window, for that matter, from code... I don't know much about C# properties, though, so I might be wrong.
Give it a try in C#.
modified on Wednesday, September 10, 2008 1:07 PM
|
|
|
|
 |
|
 |
sk8er_boy287 wrote: Let me guess... like whomever uni-voted my question?
Your guess is incorrect. Not all 1-votes are "auto univotes." Some are deserved.
|
|
|
|
 |
|
 |
I've more than over-replied on this, so I won't bother again. If I'm wrong with all my mumbojumbo, just tell me and put me out of my suffering.
|
|
|
|
 |
|
 |
The MSDN article How to Obtain Font Metrics[^] helped me come up with the FontEmSize/FontLineSpacing calculations. The rest was trial and error. Oh, and counting pixels because my calculation was off by 7 pixels.
sk8er_boy287 wrote: This article also says how you can get Dialog Base Units for non-system fonts:
http://support.microsoft.com/kb/125681[^]
I believe that the article is about how to calculate the size of a dialog box (MessageBox, etc.) based on the font. I do not think that these calculations are for textbox controls. If my assumption is incorrect (which has been known to occur from time to time ), please correct me.
modified on Tuesday, September 9, 2008 10:24 AM
|
|
|
|
 |
|
 |
That article is about computing dialog box and common control sizes.
|
|
|
|
 |
|
 |
Would it be practical to have a container control which contains one single-line textbox and includes wrapper properties so that changes to most properties (e.g. Text) will affect the textbox within? That would allow the height of the container to be set independent from the font size, and would allow for top, bottom, or middle alignment. There could also be a 'measure font size' event that would allow the parent form to have the font size vary based upon height and width (e.g. use the largest font that is reasonable given both height and width constraints).
|
|
|
|
 |
|
 |
A suggestion:
What not change your article to be about a subclassed "adjustable-height TextBox?"
Your new class could inherit from the standard TextBox and expose a single new property (*), which in the properties window of the IDE would display the textbox instance's .Height value -- and when a different value is entered in the new property, the class would invoke the method you've shown us, something like this:
[System.ComponentModel.Category("Layout")]
[System.ComponentModel.Description("Set the TextBox.Height to a specific value.")]
public int Size_AdjustedHeight
{
get {return this.Height;}
set
{
if (value != this.Height)
{
this.Font = GetFontForTextBoxHeight(value, this.Font);
}
}
}
This would have the advantage of explicitly visually showing you in the developement environment what the result will be. And, of course, you could dynamically set this property's value in the code of your application thusly: [textbox.Size_AdjustedHeight = 24;].
edit: If you like this suggestion, it would probably be good to make the GetFontForTextBoxHeight() method static in the new class. My thought here is that if one uses several instances of this new class on a form, only one copy the "resize" code is needed in memory.
(*) Say, "AdjustedHeight" Or, to cause alphabetic placement in the properties list with "Size", "Size_AdjustedHeight"
EDIT:
Of course, regardless of how one uses this method, it *does* modify the textbox's .Font.Size
In playing around with it, it seems that when the "Size_AdjustedHeight" value is set to 26 or higher, the target textbox's .Font looks bolded compared to a textbox which hasn't been so adjusted.
modified on Monday, September 8, 2008 10:21 AM
|
|
|
|
 |
|
 |
Supercat9 & Ilíon - great suggestions. I'm working on a user control now. I'll post an update when finished. Thanks for the input!
|
|
|
|
 |
|
 |
hayes.adrian wrote: Supercat9 & Ilíon - great suggestions. I'm working on a user control now. I'll post an update when finished. Thanks for the input!
Done! Enjoy!
Thanks again for your input. Great suggestions.
|
|
|
|
 |