RichTextBlock继续在UWP中的运行之间插入空格

时间:2017-02-17 09:10:26

标签: c# .net xaml uwp

我有这个非常简单的RichtTextBlock

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

在设计时,运行之间没有空格(这就是我需要的东西!),但在运行时,两个运行都用空格分隔。

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

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

对我而言,这是正确的行为。

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

Bad behavior

如何让运行连接在一起而不是间隔?

3 个答案:

答案 0 :(得分:2)

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

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

final Spliterator<Integer> spliterator = global.spliterator();

final boolean subSequence = sequence.stream().allMatch(
  itemSequence -> StreamSupport.stream(
    spliterator,
    false
  ).anyMatch(itemSequence::equals)
);

System.out.println(subSequence);

答案 1 :(得分:2)

很酷,不知道 - 就像格伦所说 - TextBlockRich侄子之间会有这样的差异; - )。

更新了我的代码以使用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));
            }
        }
    }
}

答案 2 :(得分:0)

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

~~src/HOL

用法非常简单:将它附加到RichTextBlock,您希望删除多余的空格。

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);
        }
    }
}

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

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

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

    <interactivity:Interaction.Behaviors>
        <local:RemoveEmptyRunsBehavior />
    </interactivity:Interaction.Behaviors>
</RichTextBlock>