如何消除 TextBlock 中 Run 之间的空白?

问题描述 投票:0回答:7

我有以下 XAML:

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

我得到这样的显示:

12 + 11
不知何故,它在每个
Run
之间插入了额外的空间 如何让它显示
12+11

wpf xaml
7个回答
176
投票

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 的文本属性,因此运行之间的中断之间的空白会导致您看到的效果。您也可以将其缩短为这样。

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

这篇 MSDN 文章提供了有关 xaml 如何处理空格的所有细节

http://msdn.microsoft.com/en-us/library/ms788746.aspx

如果您好奇为什么中断和大量制表符会转化为一个空格

所有空白字符(空格、换行、制表符)都会转换为 空格。

所有连续空格均被删除并替换为一个空格


50
投票

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

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

23
投票

Kevin 好的解决方案的一个问题是,当您应用一些 XAML/XML 自动重新格式化功能(例如“ctrl-K + ctrl-D”。我发现的一种解决方法是将

XAML
标签格式化,如下所示:

Run

虽然像这样跨行分割标签有点尴尬,但只要您为 XAML 文本编辑器选择 
<TextBlock> <Run FontStyle="Italic" Text="aaa" /><Run Text="bbb" /> </TextBlock>

选项“在属性之间保留新行和空格”,这种格式就不会因自动重新格式化而改变:


extra space eliminated between consecutive Run elements in XAML


2
投票

Visual Studio

完整的源代码及其解释可以在
这里

找到。 通过使用此附加属性,您可以按照您想要的方式保持 XAML 格式,但在渲染的 XAML 中不会出现这些空格。


2
投票

示例:

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

<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>



1
投票
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; } }

),然后每次

FontSize="1"
将字体大小设置为所需的大小:

<Run

您最好在代码隐藏中进行此操作。我已经尝试过以前的解决方案,但在某些情况下,VS 只是格式化掉了仔细缩进的代码。 


0
投票
<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>

内使用

<TextBlock.Inlines>
标签:
<TextBlock>

© www.soinside.com 2019 - 2024. All rights reserved.