The TextBlock
in WPF really doesn't want to trim its text. It will do so when there isn't enough space, but as soon as the ScrollViewer
can scroll, the TextBlock
thinks it has infinite space available, so it won't trim.
I think the easiest way to do this is to set the MaxWidth
on the TextBlock
to the ActualWidth
of the ListBox
:
<DataTemplate>
<TextBlock Text="{Binding}"
TextTrimming="CharacterEllipsis"
MaxWidth="{Binding ActualWidth, RelativeSource={RelativeSource AncestorType={x:Type ListBox}}}"/>
</DataTemplate>
This is going to be ever slightly too big with the default WPF ListBox
Style
(which causes the scrollbar to still appear). I would write a custom converter to subtract about 8 from this value:
public FudgeFactorConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null) return Binding.DoNothing;
return (double)value - 8; // you will probably need to tweak this
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return Binding.DoNothing;
}
}
And then use it to convert the MaxWidth
:
<DataTemplate>
<DataTemplate.Resources>
<my:FudgeFactorConverter x:Key="fudgeFactorConverter" />
</DataTemplate.Resources>
<TextBlock Text="{Binding}"
TextTrimming="CharacterEllipsis"
MaxWidth="{Binding ActualWidth, RelativeSource={RelativeSource AncestorType={x:Type ListBox}}, Converter={StaticResource fudgeFactorConverter}}"/>
</DataTemplate>
As a bonus, if you set ListBox.MinWidth
, you won't have to enable/disable the horizontal scrollbar.