1. 程式人生 > >wpf Textblock 文字過長時,中間用省略號代替。

wpf Textblock 文字過長時,中間用省略號代替。

如果是省略號載入最後,可直接用TextTrimming屬性,如果不加在最後,想將省略號加在中間,提供兩種思路。

第一種,利用三個TextBlock(txb、txb1、txb2)來實現,這種顯示出來的文字可能有半個字的現象。

txb用來顯示不過長的文字,txb1和txb2用來顯示過長時,文字的前後兩部分,txb1和txb2的可見性和 txb相反。

三者的樣式(txb和txb1要設定TextTrimming,txb2要設定HorizontalAlignment為right)

 <TextBlock x:Name="txb" SizeChanged="txb_SizeChanged" Grid.Row="1" Grid.ColumnSpan="2" Background="LightGray" TextTrimming="CharacterEllipsis"/>
            <TextBlock x:Name="txb1" Grid.Column="0" VerticalAlignment="Center"  Visibility="{Binding ElementName=txb,Path=Visibility,Converter={StaticResource visiblieConverter}}"
                                                               TextTrimming="CharacterEllipsis"                  >
            </TextBlock>
            <TextBlock x:Name="txb2" Grid.Column="1" VerticalAlignment="Center"  Visibility="{Binding ElementName=txb,Path=Visibility,Converter={StaticResource visiblieConverter}}"                                                                 HorizontalAlignment="Right"               >

當txb大小變化時,要判斷是否文字過長,如果過長則顯示txb1和txb2,否則顯示txb

private void txb_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            TextBlock textBlock = sender as TextBlock;
            if (textBlock != null)
            {
                string str = textBlock.Text;
                Typeface typeface = new Typeface(
           textBlock.FontFamily,
           textBlock.FontStyle,
           textBlock.FontWeight,
           textBlock.FontStretch);
                FormattedText formattedText = new FormattedText(
                    str,
                    System.Threading.Thread.CurrentThread.CurrentCulture,
                    textBlock.FlowDirection,
                    typeface,
                    textBlock.FontSize,
                    textBlock.Foreground);
                if (textBlock.ActualWidth + 1 < formattedText.Width)
                {
                    textBlock.Visibility = Visibility.Hidden;
                }
                else
                {
                    textBlock.Visibility = Visibility.Visible;
                }
            }
        }

第二種,後臺來生成適合Textblock大小的文字。

       <TextBlock x:Name="txb11" SizeChanged="txb_SizeChanged1" Grid.Row="0" Grid.ColumnSpan="2" Background="LightGray" TextTrimming="CharacterEllipsis"/>
            <TextBlock x:Name="txb12"  Grid.Row="1" Grid.ColumnSpan="2"    />

利用二分法找到要擷取的字串

private void txb_SizeChanged1(object sender, SizeChangedEventArgs e)
        {
            TextBlock textBlock = sender as TextBlock;
            if (textBlock != null)
            {
                string str = textBlock.Text;
                Typeface typeface = new Typeface(
           textBlock.FontFamily,
           textBlock.FontStyle,
           textBlock.FontWeight,
           textBlock.FontStretch);
                FormattedText formattedText = new FormattedText(
                    str,
                    System.Threading.Thread.CurrentThread.CurrentCulture,
                    textBlock.FlowDirection,
                    typeface,
                    textBlock.FontSize,
                    textBlock.Foreground);
                if (textBlock.ActualWidth + 1 < formattedText.Width)
                {
                    string str1 = textBlock.Text;
                    int p1 = findPosition(str1, typeface, textBlock);
                    char[] ret = str1.ToCharArray();
                    string str2 = string.Concat<char>(ret.Reverse<char>());
                    int p2 = findPosition(str2, typeface, textBlock);
                    string strOutPut = str.Substring(0, p1) + "..." + str.Substring(str.Length - p2, p2);
                    txb12.Text = strOutPut;
                }
                else
                {
                    txb12.Text = txb11.Text;
                }
            }

        }

        private int findPosition(string str, Typeface typeface, TextBlock textBlock)
        {
            int start = 0, end = str.Length - 1;
            while (start <= end)
            {
                int mid = (start + end) / 2;
                string strTemp = str.Substring(0, mid);
                FormattedText formattedText = new FormattedText(
                    strTemp,
                    System.Threading.Thread.CurrentThread.CurrentCulture,
                    textBlock.FlowDirection,
                    typeface,
                    textBlock.FontSize,
                    textBlock.Foreground);
                if (formattedText.Width <= (txb11.ActualWidth - 10) / 2)
                    start = mid + 1;
                else
                    end = mid - 1;
            }
            if (start == 0)
                return -1;
            else
                return start - 1;
        }

顯示效果

程式碼路徑