I need to display a block of text in a resizable column. The text should wrap with overflow but, for a given column size, the user should be able to scroll horizontally to view the overflown text.
I do not believe this can be achieved w/ out of the box controls; if I'm wrong about that please tell me. I have attempted to achieve this with a custom control:
public class Sizer : ContentPresenter
{
static Sizer()
{
ContentPresenter.ContentProperty.OverrideMetadata(typeof(Sizer), new FrameworkPropertyMetadata(ContentChanged)); ;
}
public Sizer() : base() {}
protected override Size MeasureOverride(Size constraint)
{
var childWidth = Content==null ? 0.0 : ((FrameworkElement)Content).RenderSize.Width;
var newWidth = Math.Max(RenderSize.Width, childWidth);
return base.MeasureOverride(new Size(newWidth, constraint.Height));
}
private static void ContentChanged(DependencyObject dep, DependencyPropertyChangedEventArgs args)
{
var @this = dep as Sizer;
var newV = args.NewValue as FrameworkElement;
var oldV = args.OldValue as FrameworkElement;
if (oldV != null)
oldV.SizeChanged -= @this.childSizeChanged;
if(newV!=null)
newV.SizeChanged += @this.childSizeChanged;
}
private void childSizeChanged(object sender, SizeChangedEventArgs e)
{
this.InvalidateMeasure();
}
}
...and I can test it in a simple WPF application like so:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<ScrollViewer Grid.Column="0" VerticalScrollBarVisibility="Disabled" HorizontalScrollBarVisibility="Auto" VerticalAlignment="Top">
<local:Sizer>
<local:Sizer.Content>
<TextBlock Background="Coral" Text="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaa"
TextWrapping="WrapWithOverflow" />
</local:Sizer.Content>
</local:Sizer>
</ScrollViewer>
<GridSplitter Grid.Column="1" Background="Black" VerticalAlignment="Stretch" HorizontalAlignment="Left" Width="5" />
</Grid>
This works, after a fashion. It wraps and displays the text correctly, and the horizontal scrollbar lets me view the overflown text. If I resize the column to the right (larger) the text re-wraps correctly. However, if I resize the column to the left (smaller) the text will not re-wrap. So, for instance, if I resize the column to the right so that all the text is on one line it will remain all on one line regardless of any subsequent re-sizing. This is an unacceptable bug.
I have tinkered w/ this code a great deal although I haven't had what you'd a call a good strategy for finding a solution. I do not know and have not been able to discover any mechanism for forcing a textblock to re-wrap its contents. Any advice?