Reputation: 1233
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 textblock? and how to make it autosize?
Upvotes: 7
Views: 19498
Reputation: 139256
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.
Upvotes: 1
Reputation: 6175
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);
}
}
}
Upvotes: 3
Reputation: 3331
Here is a different way of solving this issue.
Set yourTextBlock.Width = double.NaN
and same with Height
.
Upvotes: 4
Reputation: 9223
You can get the size of a text using these solutions :
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);
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 !
Upvotes: 7
Reputation: 6460
Textblocks that have no height or width specified will expand automatically until they fill their container. So try that.
Upvotes: 7