views:

934

answers:

3

I have a WPF ListView (GridView) and the cell template contains a TextBlock. If I add: TextTrimming="CharacterEllipsis" TextWrapping="NoWrap" on the TextBlock, an ellipsis will appear at the end of my string when the column gets smaller than the length of the string. What I need is to have the ellipsis at the beginning of the string.

I.e. if I have the string Hello World!, I would like ...lo World!, instead of Hello W....

Any ideas?

+1  A: 

Unfortunately, this is not possible in WPF today, as you can see from the documentation.

(I used to work at Microsoft on WPF, this was a feature we unfortunately did not get around to doing -- not sure if it's planned for a future version)

Fortes
+1  A: 

You could try to use a ValueConverter (cf. IValueConverter interface) to change the strings that should be displayed in the list box yourself. That is, in the implementation of the Convert method, you would test if the strings are longer than the available space, and then change them to ... plus the right side of the string.

EFrank
Yeah that's what I did in the end and it works like a charm ;) Thanks!
Simon Levy
A: 

Here is an example how to do an efficient text clipping with a recursive logarithmic algorithm:

private static string ClipTextToWidth(
    TextBlock reference, string text, double maxWidth)
{
    var half = text.Substring(0, text.Length/2);

    if (half.Length > 0)
    {
        reference.Text = half;
        var actualWidth = reference.ActualWidth;

        if (actualWidth > maxWidth)
        {
            return ClipTextToWidth(reference, half, maxWidth);
        }

        return half + ClipTextToWidth(
            reference,
            text.Substring(half.Length, text.Length - half.Length),
            maxWidth - actualWidth);
    }
    return string.Empty;
}

Suppose you have a TextBlock field named textBlock, and you want to clip the text in it at a given maximal width, with the ellipsis appended. The following method calls ClipTextToWidth to set the text for the textBlock field:

public void UpdateTextBlock(string text, double maxWidth)
{
    if (text != null)
    {
        this.textBlock.Text = text;

        if (this.textBlock.ActualWidth > maxWidth)
        {
            this.textBlock.Text = "...";
            var ellipsisWidth = this.textBlock.ActualWidth;

            this.textBlock.Text = "..." + ClipTextToWidth(
                this.textBlock, text, maxWidth - ellipsisWidth);
        }
    }
    else
    {
        this.textBlock.Text = string.Empty;
    }
}

Hope that helps!

dadinn