2

Silverlight (少なくともバージョン 4 の時点) には、WPFCharacterEllipsisにある のオプションがありません。で使用できます。つまり、「それは信じられない」を表示する十分なスペースがない場合、「それは...」にトリミングできますが、「それは信じられない...」にはトリミングできません。TextTrimmingTextBlock

ただし、カスタム テキスト トリミング機能を実装してみます。基本的に、それほど難しいことではありません。非常にばかげた方法は、文字列のピクセルを測定し、使用可能な幅と比較し、最後の文字を切り取り、テキストがまだ収まらない間に "..." をループに追加して文字列を操作することです。これがどのように機能するかの例を次に示します。

// Not perfect but good enough for us
private bool AutoTrim(string fullText, TextBlock textBlock, double maxWidth)
{
    double factor = maxWidth / textBlock.ActualWidth;
    if (factor > 1)
        return false;

    int newTextLength = (int)Math.Floor((double)fullText.Length * factor);
    string trimTest;
    do
    {
        trimTest = fullText.Substring(0, newTextLength--);
        textBlock.Text = trimTest + "..."; // problematic...
        factor = maxWidth / textBlock.ActualWidth;
    }
    while (factor < 1 && newTextLength > 0);

    return true;
}

しかし、コード ビハインド (または 内Behavior) でそれを行うと、いくつかの問題が発生しますTextBlock1.Text = ...。view と viewModel が何らかの理由で同期していない可能性があることに気付いたため、別の問題が発生しました (ListBox で気付きました)。

この問題を良い方法で解決する方法について、より良いアイデアはありますか?

4

4 に答える 4

5

Robby Ingebretsen のDynamicTextBoxは、TextBlock をカスタム コントロールでラップし、使用可能なサイズを測定することでこれを行います。これは、WPF の CharacterEllipsis テキスト トリミング モードと一致します。WordEllipsis モードは Windows Phone 7 Mango に追加されましたが、ここではあまり役に立ちません。

于 2011-12-29T23:05:14.940 に答える
3

Dan Wahlin は TextTrimming="WordEllipsis" が Silverlight 4 に追加される前にコンバーターを使用していました。 -4.aspx

于 2011-06-01T06:51:55.160 に答える
1

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 の幅が指定された最大値より小さくなるまで繰り返されます。

私が言ったように、それは完璧ではなく、特にエレガントでもありませんが、上記のような例では問題なく動作します.

LayoutUpdated イベントを使用するという考えは好きではありませんが、別の適切なイベントが見つかりませんでした。残念ながら、TextChanged は TextBlock には存在しません:(

何か改善できることがあれば教えてください。

于 2014-03-19T05:23:45.847 に答える