Edward_jie

for you, my Hall of Frame

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  92 随笔 :: 45 文章 :: 539 评论 :: 43万 阅读
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

顺利解决textblock显示文字不完全的问题:

There could be many scenarios when you'd need to be able to dipslay a text in your WP7 application which doesn't fit on the screen. The easiest way to approach to solve this would be to utilize the ScrollViewer control as a host for a TextBlock. Something like that:

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
      <ScrollViewer>
            <TextBlock x:Name="textBlock" TextWrapping="Wrap" />
      </ScrollViewer>
</Grid>

You would think that we're done but as usual the "devil is in the details". If you assign a long text to the TextBlock you will see that part of this text could be truncated and an empty space would be displayed when scrolling to the end:

 The reason for this behavior is that any element that must be displayed beyond the area which is larger than 2048x2048 pixels would be clipped by the platform. I was told that this limitation had been dictated by a combination of hardware limitation and performance considerations. To workaround this limitation we'd need to break out the text into a separate blocks and create a TextBlock for each of this text blocks. So to make the life easier for myself and for you I created a custom control which I called ScrollableTextBlock which wraps this logic. So I created a custom control which derives from Control and implements Text property:

    public class ScrollableTextBlock : Control
    {
        private StackPanel stackPanel;
        
        public ScrollableTextBlock()
        {
            // Get the style from generic.xaml
            this.DefaultStyleKey = typeof(ScrollableTextBlock);           
        }

        public static readonly DependencyProperty TextProperty =
            DependencyProperty.Register(
                "Text",
                typeof(string),
                typeof(ScrollableTextBlock),
                new PropertyMetadata("ScrollableTextBlock", OnTextPropertyChanged));        

        public string Text
        {
            get
            {
                return (string)GetValue(TextProperty);
            }
            set
            {
                SetValue(TextProperty, value);
            }
        }

        private static void OnTextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ScrollableTextBlock source = (ScrollableTextBlock)d;
            string value = (string)e.NewValue;
            source.ParseText(value);
        }

            }

And here's the ParseText method which is also a part of this control:

    private void ParseText(string value)
    {
         if (this.stackPanel == null)
         {
             return;
         }
         // Clear previous TextBlocks
         this.stackPanel.Children.Clear();
         // Calculate max char count
         int maxTexCount = this.GetMaxTextSize();

         if (value.Length < maxTexCount)
         {
             TextBlock textBlock = this.GetTextBlock();
             textBlock.Text = value;
             this.stackPanel.Children.Add(textBlock);
         }
         else
         {
             int n = value.Length / maxTexCount;
             int start = 0;
            // Add textblocks
             for (int i = 0; i < n; i++)
             {                    
                 TextBlock textBlock = this.GetTextBlock();
                 textBlock.Text = value.Substring(start, maxTexCount);
                 this.stackPanel.Children.Add(textBlock);
                 start = maxTexCount;
             }

             // Pickup the leftover text
             if (value.Length % maxTexCount > 0)
             {
                 TextBlock textBlock = this.GetTextBlock();
                 textBlock.Text = value.Substring(maxTexCount * n, value.Length - maxTexCount * n);
                 this.stackPanel.Children.Add(textBlock);                   
             }
         }
     }

In the code above I measure the text length and if it's greater that maxTextCount I break the text into a separate blocks and create a new TextBlock with this text. After the TextBlock is created I add it to the StackPanel. To make a picture complete here's how the control's style looks like:

   <Style TargetType="local:ScrollableTextBlock" >
        <Setter Property="Foreground" Value="{StaticResource PhoneForegroundBrush}"/>
        <Setter Property="Background" Value="Transparent"/>
        <Setter Property="FontSize" Value="{StaticResource PhoneFontSizeMedium}"/>
        <Setter Property="Padding" Value="0"/>
        <Setter Property="Width" Value="200" />
        <Setter Property="Height" Value="70" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="local:ScrollableTextBlock">
                    <ScrollViewer x:Name="ScrollViewer" Foreground="{TemplateBinding Foreground}" 
                                  Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" 
                                  BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}">
                        <StackPanel Orientation="Vertical" x:Name="StackPanel" />
                    </ScrollViewer>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

As you can see, the StackPanel is located inside of the ScrollViewer control which provides the scrolling functionality.  And after we execute the test project the result is that the text is not truncated:

 

原文作者:Alex Takhnin's Blog

posted on   Edward_诺  阅读(1465)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述
点击右上角即可分享
微信分享提示