Вот как я обошел отсутствие опции CharacterEllipsis.Мое решение тоже не идеально, но оно до сих пор работало для меня.
Сначала я добавил следующий вспомогательный метод:
public static void AutoTrimTextBlock(TextBlock textBlock, double maxWidth)
{
if (!string.IsNullOrWhiteSpace(textBlock.Text))
{
var currentWidth = textBlock.ActualWidth;
if (currentWidth > maxWidth)
{
if (textBlock.Text.Length > 2)
{
int substrLength = textBlock.Text.Length - 1;
if (textBlock.Text[substrLength] == '…')
substrLength--;
textBlock.Text = textBlock.Text.Substring(0, substrLength) + '…';
}
else if (textBlock.Text.Length == 2)
{
if (textBlock.Text[1] == '…')
textBlock.Text = "…";
else
textBlock.Text = textBlock.Text[0].ToString() + '…';
}
else //implies: if (length == 1)
{
textBlock.Text = string.Empty;
}
}
}
}
Затем я обновил свой XAML, чтобы он выглядел так:
<Grid x:Name="MyGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="Column0" Width="Auto"/>
<ColumnDefinition x:Name="Column1" Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" x:Name="SomeOtherText" Text="{Binding OtherString}"/>
<TextBlock Grid.Column="1" x:Name="MyTextBlock"
TextWrapping="NoWrap" <!--Disable text wrapping-->
TextTrimming="None" <!--Disable built-in text trimming-->
Text="{Binding MyString, Mode=OneWay}" <!--OneWay binding avoids writing trimmed text back to view model-->
LayoutUpdated="MyTextBlock_LayoutUpdated"/> <!--LayoutUpdated event will trigger custom text trimming-->
</Grid>
Наконец, в коде я добавил следующее:
void MyTextBlock_LayoutUpdated(object sender, System.EventArgs e)
{
// Calculate maximum width for MyTextBlock.
// I did it by checking the parent column width,
// but you can do it any way you like.
double maxWidth = Column1.ActualWidth - MyTextBlock.Margin.Left - MyTextBlock.Margin.Right;
// Start trimming
AutoTrimTextBlock(MyTextBlock, maxWidth);
}
Результат: при каждом изменении свойства MyString вызывается обработчик события LayoutUpdated и метод AutoTrimTextBlock ()называется.Если MyTextBlock слишком широкий, его свойство Text обрезается и добавляется «…».Это вызывает другое событие LayoutUpdated.Процесс повторяется до тех пор, пока ширина MyTextBlock не станет меньше указанного максимума.
Как я уже сказал, он не идеален и не особенно элегантен, но он хорошо работает в примерах, подобных приведенному выше.
IМне не нравится идея использовать событие LayoutUpdated, но я не смог найти другое подходящее.К сожалению, TextChanged не существует для TextBlock: (
Пожалуйста, дайте мне знать, если я могу что-то улучшить.