XAML 如何在TextBlock中消除中间空格?

nfs0ujit  于 12个月前  发布在  其他
关注(0)|答案(7)|浏览(198)

下面是XAML:

<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center"
                                               FontSize="10" FontFamily="Arial" Foreground="#414141">        
                                            <Run Text="{Binding LoadsCount}" />        
                                            <Run Text="+" />        
                                            <Run Text="{Binding BrokerLoadsCount}" />
                                        </TextBlock>

字符串
我得到这样的显示:不知何故,它在每个Run之间插入了额外的空间,我怎么让它显示12+11

5anewei6

5anewei61#

run标签之间的空格导致空格,这是最简单的修复方法。

<TextBlock 
   HorizontalAlignment="Center" 
   VerticalAlignment="Center"
   FontSize="10" 
   FontFamily="Arial" 
   Foreground="#414141">        
      <Run Text="{Binding LoadsCount}" /><Run Text="+" /><Run Text="{Binding BrokerLoadsCount}" />
</TextBlock>

字符串
因为<TextBlock></TextBlock>之间的任何东西都是针对TextBlock的text属性的,所以运行之间的空格会导致你看到的效果。你也可以把它缩短为这样。

<Run Text="{Binding LoadsCount}" />+<Run Text="{Binding BrokerLoadsCount}" />


这篇MSDN文章给出了xaml如何处理空白的所有细节
http://msdn.microsoft.com/en-us/library/ms788746.aspx
如果你好奇为什么一个空格和大量的制表符转换成一个空格,
所有空白字符(空格、换行符、制表符)都转换为空格。
所有连续的空格将被删除并替换为一个空格

a64a0gku

a64a0gku2#

另一种选择是注解Run标记之间的空格,保持代码可读并删除多余的空格。

<TextBlock HorizontalAlignment="Center"
           VerticalAlignment="Center"
           FontSize="10" FontFamily="Arial" Foreground="#414141">        
    <Run Text="{Binding LoadsCount}" /><!--
 --><Run Text="+" /><!--
 --><Run Text="{Binding BrokerLoadsCount}" />
</TextBlock>

字符串

wvyml7n5

wvyml7n53#

Kevin的好解决方案的一个问题是,当你应用一些XAML/XML自动重新格式化函数时,XAML标签的单行格式被撤销,例如“ctrl-K + ctrl-D”。我发现的一个解决方案是如下格式化Run标签:

<TextBlock>
    <Run FontStyle="Italic"
    Text="aaa" /><Run 
    Text="bbb" />
</TextBlock>

字符串
虽然像这样将标记跨行拆分有点尴尬,但如果您为XAML文本编辑器选择Visual Studio选项“保留属性之间的新行和空格”,则自动重新格式化不会更改此格式:
x1c 0d1x的数据

nfzehxib

nfzehxib4#

我已经写了一个附加属性来'绕过'这种行为。

public class TextBlockExtension
{

    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 TextBlock;
            if (tb != null)
            {
                tb.Loaded += Tb_Loaded;
            }
            else
            {
                throw new NotSupportedException();
            }
        }
    }

    public static readonly DependencyProperty RemoveEmptyRunsProperty =
        DependencyProperty.RegisterAttached("RemoveEmptyRuns", typeof(bool), 
            typeof(TextBlock), 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 TextBlock;
        tb.Loaded -= Tb_Loaded;

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

字符串
整个源代码和解释都可以在here中找到。通过使用此附加属性,您可以按照自己的方式保持XAML格式,但不会在呈现的XAML中获得这些空格。

xesrikrc

xesrikrc5#

我将Pieter的附加属性移植到WPF(我认为这是UWP)。
范例:

<StackPanel>
    <TextBlock Text="Before:" FontWeight="SemiBold"/>
    <TextBlock>
        Foo
        <Run Text="Bar"/>
        <Run>Baz</Run>
    </TextBlock>
    <TextBlock Text="After:" FontWeight="SemiBold" Margin="0,10,0,0"/>
    <TextBlock local:TextBlockHelper.TrimRuns="True">
        Foo
        <Run Text="Bar"/>
        <Run>Baz</Run>
    </TextBlock>
    <TextBlock Text="Use two spaces if you want one:" FontWeight="SemiBold" Margin="0,10,0,0"/>
    <TextBlock local:TextBlockHelper.TrimRuns="True">
        Foo
        <Run Text="  Bar"/>
        <Run>Baz</Run>
    </TextBlock>
</StackPanel>

字符串


的数据

using System;
using System.Linq;
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;

public class TextBlockHelper
{
    public static bool GetTrimRuns(TextBlock textBlock) => (bool)textBlock.GetValue(TrimRunsProperty);
    public static void SetTrimRuns(TextBlock textBlock, bool value) => textBlock.SetValue(TrimRunsProperty, value);

    public static readonly DependencyProperty TrimRunsProperty =
        DependencyProperty.RegisterAttached("TrimRuns", typeof(bool), typeof(TextBlockHelper),
            new PropertyMetadata(false, OnTrimRunsChanged));

    private static void OnTrimRunsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var textBlock = d as TextBlock;
        textBlock.Loaded += OnTextBlockLoaded;
    }

    static void OnTextBlockLoaded(object sender, EventArgs args)
    {
        var textBlock = sender as TextBlock;
        textBlock.Loaded -= OnTextBlockLoaded;

        var runs = textBlock.Inlines.OfType<Run>().ToList();
        foreach (var run in runs)
            run.Text = TrimOne(run.Text);
    }

    private static string TrimOne(string text)
    {
        if (text.FirstOrDefault() == ' ')
            text = text.Substring(1);
        if (text.LastOrDefault() == ' ')
            text = text.Substring(0, text.Length - 1);

        return text;
    }
}

pkmbmrz7

pkmbmrz76#

我的解决方案是使默认字体大小几乎不可见(FontSize="1"),然后在每<Run处将字体大小设置为所需的大小:

<TextBlock HorizontalAlignment="Center"
           VerticalAlignment="Center"
           FontSize="1"
           FontFamily="Arial"
           Foreground="#414141">        

    <Run FontSize="10" Text="{Binding LoadsCount}" />        
    <Run FontSize="10" Text="+" />        
    <Run FontSize="10" Text="{Binding BrokerLoadsCount}" />
</TextBlock>

字符串
你最好还是在Code Behind中做,我试过以前的解决方案,但在某些情况下,VS只是格式化了小心缩进的代码。

des4xlb0

des4xlb07#

另一个看起来更干净的解决方案是在<TextBlock>中使用<TextBlock.Inlines>标签:

<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center"
                   FontSize="10" FontFamily="Arial" Foreground="#414141">
            <TextBlock.Inlines>
                <Run Text="{Binding LoadsCount}" />        
                <Run Text="+" />        
                <Run Text="{Binding BrokerLoadsCount}" />
            </TextBlock.Inlines>
</TextBlock>

字符串

相关问题