how to make wpf textblock autosize
i have a textblock where i dynamically add string.. even if i add string width and update the textblock the textblock is not showing appropriate width, still some text are cut..
how to measure width that has to be displayed in textbl开发者_StackOverflow社区ock? and how to make it autosize?
You can get the size of a text using these solutions :
Solution 1
You could FormattedText to measure the size of text, here is an example:
String text = "Here is my text";
Typeface myTypeface = new Typeface("Helvetica");
FormattedText ft = new FormattedText(text, CultureInfo.CurrentCulture,
FlowDirection.LeftToRight, myTypeface, 16, Brushes.Red);
Size textSize = new Size(ft.Width, ft.Height);
Solution 2
Use the Graphics class (found here ):
System.Drawing.Font font = new System.Drawing.Font("Calibri", 12, FontStyle.Bold);
Bitmap bitmap = new Bitmap(1, 1);
Graphics g = Graphics.FromImage(bitmap);
SizeF measureString = g.MeasureString(text, font);
Here you are !
Textblocks that have no height or width specified will expand automatically until they fill their container. So try that.
Here is a different way of solving this issue.
Set yourTextBlock.Width = double.NaN
and same with Height
.
Here's a class i've written that does this. It only AutoShrinks but you can add the functionality you need. It uses the parent bounds OR MaxHeight / MaxWidth if they are set.
public class TextBlockAutoShrink : TextBlock
{
// private Viewbox _viewBox;
private double _defaultMargin = 6;
private Typeface _typeface;
static TextBlockAutoShrink()
{
TextBlock.TextProperty.OverrideMetadata(typeof(TextBlockAutoShrink), new FrameworkPropertyMetadata(new PropertyChangedCallback(TextPropertyChanged)));
}
public TextBlockAutoShrink() : base()
{
_typeface = new Typeface(this.FontFamily, this.FontStyle, this.FontWeight, this.FontStretch, this.FontFamily);
base.DataContextChanged += new DependencyPropertyChangedEventHandler(TextBlockAutoShrink_DataContextChanged);
}
private static void TextPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
{
var t = sender as TextBlockAutoShrink;
if (t != null)
{
t.FitSize();
}
}
void TextBlockAutoShrink_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
{
FitSize();
}
protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo)
{
FitSize();
base.OnRenderSizeChanged(sizeInfo);
}
private void FitSize()
{
FrameworkElement parent = this.Parent as FrameworkElement;
if (parent != null)
{
var targetWidthSize = this.FontSize;
var targetHeightSize = this.FontSize;
var maxWidth = double.IsInfinity(this.MaxWidth) ? parent.ActualWidth : this.MaxWidth;
var maxHeight = double.IsInfinity(this.MaxHeight) ? parent.ActualHeight : this.MaxHeight;
if (this.ActualWidth > maxWidth)
{
targetWidthSize = (double)(this.FontSize * (maxWidth / (this.ActualWidth + _defaultMargin)));
}
if (this.ActualHeight > maxHeight)
{
var ratio = maxHeight / (this.ActualHeight);
// Normalize due to Height miscalculation. We do it step by step repeatedly until the requested height is reached. Once the fontsize is changed, this event is re-raised
// And the ActualHeight is lowered a bit more until it doesnt enter the enclosing If block.
ratio = (1 - ratio > 0.04) ? Math.Sqrt(ratio) : ratio;
targetHeightSize = (double)(this.FontSize * ratio);
}
this.FontSize = Math.Min(targetWidthSize, targetHeightSize);
}
}
}
By default, elements have an HorizontalAligment
and VerticalAligment
properties that are set to Stretch
, so they will adapt to their parent.
But if you set these to Center
, the element will keep its natural size, so you can test this (or setting properties using code instead of XAML):
<TextBlock Text="This is my text"
HorizontalAlignment="Center"
VerticalAlignment="Center"
/>
It worked in my case, maybe not in every case.
MyTextBlock.TextWrapping = TextWrapping.Wrap;
精彩评论