For textblocks in wpf one can (easily) set the minimal, maximal and actual width/height.
Now in my case I have a textblock with potentially quite a bit of information. Which can be wrapped around. I wish that information to be contained on a specified "line" - maximum height. However the textblock should also adhere to a "prefered" width - the width CAN grow however if need be.
Thus: first word wrap and grow height while keeping width. Then once height is a certain value, stop growing that and start widening.
What I have so far is (importing relevant libraries for TextBlock
and TextWrapping
):
var tb = new TextBlock
tb.TextWrapping = TextWrapping.Wrap;
tb.Width = 96;
tb.MaxHeight = 96;
Obviously this just "fixes" the Width
, where the height just grows to a maximum afterwich the text just overflows.
You might be looking for a begavior like this:
public class TextBlockBehavior : Behavior<TextBlock>
{
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.SizeChanged += AssociatedObject_SizeChanged;
}
protected override void OnDetaching()
{
base.OnDetaching();
AssociatedObject.SizeChanged -= AssociatedObject_SizeChanged;
}
private void AssociatedObject_SizeChanged(object sender, SizeChangedEventArgs e)
{
TextBlock temp = new TextBlock()
{
Text = AssociatedObject.Text,
LineStackingStrategy = AssociatedObject.LineStackingStrategy,
LineHeight = AssociatedObject.LineHeight,
TextTrimming = TextTrimming.None,
TextWrapping = AssociatedObject.TextWrapping,
Height = AssociatedObject.Height
};
double maxwidth = AssociatedObject.MaxWidth - 10;
double desiredHeight = double.PositiveInfinity;
while (desiredHeight > AssociatedObject.MaxHeight)
{
temp.Measure(new Size(maxwidth, double.PositiveInfinity));
maxwidth += 10;
desiredHeight = temp.DesiredSize.Height;
}
AssociatedObject.MaxWidth = maxwidth;
}
}
Note that a temporary TextBlock is measured, based on the current maximum width. Using its desired size, we can decide whether to increase the maximum width or do nothing.
You should set MaxHeight
and MaxWidth
properties. Test:
<TextBlock MaxHeight="50" MaxWidth="100" Background="Red" TextTrimming="None" TextWrapping="Wrap" MouseDown="TextBlock_MouseDown">
<i:Interaction.Behaviors>
<local:TextBlockBehavior />
</i:Interaction.Behaviors>
</TextBlock>
and code:
private void TextBlock_MouseDown(object sender, MouseButtonEventArgs e)
{
((TextBlock)sender).Text += "AAAA ";
}
You might need to change somethings in cloning the textblock or changing the logic or changing the step size (I choose 10 pts here).