【问题标题】:RichTextBlock keeps inserting spaces between Runs in UWPRichTextBlock 不断在 UWP 中的 Run 之间插入空格
【发布时间】:2017-07-06 17:35:28
【问题描述】:

我有这个很简单的RichtTextBlock:

    <RichTextBlock VerticalAlignment="Center">
        <Paragraph>
            <Run Text="Hello" />
            <Run Text="world" />
        </Paragraph>
    </RichTextBlock>

在设计时,Run 之间没有空格(这正是我需要的!),但在运行时,两个 Run 之间用空格隔开。

为了说明问题,以下是快照:

在 Visual Studio 设计器中,它的呈现方式如下:

对我来说这是正确的行为。

但是,在运行时,它呈现如下:

如何使 Run 连接在一起而不是分开??

【问题讨论】:

    标签: c# .net xaml uwp


    【解决方案1】:

    Pieter Nijs 创建了一个附加属性来解决这个问题! 详情见his blog here...

    简而言之,它将从运行中获取所有可用文本,并在推出文本之前消除它找到的空格。

    var spaces = tb.Inlines.Where(a => a is Run 
            && ((Run)a).Text == " "
            && !GetPreserveSpace(a)).ToList();
        spaces.ForEach(s => tb.Inlines.Remove(s));
    

    【讨论】:

    • 它似乎只适用于 TextBlock。在 UWP 中,我们使用 RichTextBlock,它似乎具有不同的结构。例如,它没有“内联”,而是“块”。您可以发布 RichTextBlock 的代码吗? :) 提前致谢!
    • 哦...不,抱歉实际上没有意识到 RichTextBlock 和常规 TextBlock O_o 会有差异
    • 是的,它的工作方式似乎有点不同。我现在正在尝试自己,但我不知道这将如何结束。如果你这么好心让它适用于 RichTextBlock,那就太棒了!
    【解决方案2】:

    酷,不知道 - 就像格伦所说 - TextBlock 和它的 Rich 侄子之间会有这样的区别;-)。

    更新了我的代码以使用 RichTextBlock(可能需要一些额外的调整,但它似乎在提供的场景中工作)。

    public class RichTextBlockExtension
    {
        public static bool GetRemoveEmptyRuns(DependencyObject obj)
        {
            return (bool)obj.GetValue(RemoveEmptyRunsProperty);
        }
    
        public static void SetRemoveEmptyRuns(DependencyObject obj, bool value)
        {
            obj.SetValue(RemoveEmptyRunsProperty, value);
    
            if (value)
            {
                var tb = obj as RichTextBlock;
                if (tb != null)
                {
                    tb.Loaded += Tb_Loaded;
                }
                else
                {
                    throw new NotSupportedException();
                }
            }
        }
    
        public static readonly DependencyProperty RemoveEmptyRunsProperty =
        DependencyProperty.RegisterAttached("RemoveEmptyRuns", typeof(bool),
        typeof(RichTextBlock), new PropertyMetadata(false));
    
    
    
        public static bool GetPreserveSpace(DependencyObject obj)
        {
            return (bool)obj.GetValue(PreserveSpaceProperty);
        }
    
        public static void SetPreserveSpace(DependencyObject obj, bool value)
        {
            obj.SetValue(PreserveSpaceProperty, value);
        }
    
        public static readonly DependencyProperty PreserveSpaceProperty =
        DependencyProperty.RegisterAttached("PreserveSpace", typeof(bool),
        typeof(Run), new PropertyMetadata(false));
    
    
        private static void Tb_Loaded(object sender, RoutedEventArgs e)
        {
            var tb = sender as RichTextBlock;
            tb.Loaded -= Tb_Loaded;
    
            foreach (var item in tb.Blocks)
            {
                Paragraph p = item as Paragraph;
                if(p!=null)
                {
                    var spaces = p.Inlines.Where(a => a is Run
                       && ((Run)a).Text == " "
                       && !GetPreserveSpace(a)).ToList();
                                spaces.ForEach(s => p.Inlines.Remove(s));
                }
            }
        }
    }
    

    【讨论】:

      【解决方案3】:

      好的,在阅读了 Pieter Nijs 的帖子后,我为 UWP 创建了一个适用于通用 Windows 应用程序的行为。

      public class RemoveEmptyRunsBehavior : Behavior<RichTextBlock>
      {
          protected override void OnAttached()
          {
              RemoveWhitespaceRuns(this.AssociatedObject);
          }
      
          private void RemoveWhitespaceRuns(RichTextBlock tb)
          {
              var tuples = from p in tb.Blocks.OfType<Paragraph>()
                  from r in p.Inlines.OfType<Run>()
                  where r.Text == " "
                  select new { Paragraph = p, Run = r };
      
              foreach (var tuple in tuples)
              {
                  tuple.Paragraph.Inlines.Remove(tuple.Run);
              }
          }
      }
      

      用法很简单:把它附加到你想要去除多余空格的RichTextBlock上。

      <RichTextBlock VerticalAlignment="Center">
          <Paragraph>
              <Run Text="Hello" />
              <Run Text="world" />
          </Paragraph>
      
          <interactivity:Interaction.Behaviors>
              <local:RemoveEmptyRunsBehavior />
          </interactivity:Interaction.Behaviors>
      </RichTextBlock>
      

      不要忘记为 UWP 添加 XAML 行为(来自 NuGet):Microsoft.Xaml.Behaviors.Uwp.Managed

      并添加此命名空间前缀声明!

      xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
      

      【讨论】:

        猜你喜欢
        • 2021-09-23
        • 1970-01-01
        • 2012-10-08
        • 2014-12-26
        • 1970-01-01
        • 2018-07-06
        • 2019-10-14
        • 2018-05-10
        相关资源
        最近更新 更多