it-swarm.com.de

Wie kann man Leerzeichen zwischen den Runs in TextBlock entfernen?

Ich habe folgendes XAML:

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

Und ich bekomme die Anzeige wie folgt: 12 + 11 Irgendwie fügt es zusätzlichen Abstand zwischen jeder RunWie kann ich es 12+11 anzeigen lassen?

49
katit

Die Leerzeichen zwischen den Lauf-Tags verursachen die Leerzeichen. Dies ist die einfachste Lösung.

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

Da irgendetwas zwischen <TextBlock> und </TextBlock> auf die Texteigenschaft des TextBlock abzielt, bewirkt der Leerraum aus den Unterbrechungen zwischen den Läufen den Effekt, den Sie sehen. Sie könnten es auch hier verkürzen.

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

Dieser MSDN-Artikel enthält alle Einzelheiten dazu, wie Xaml mit dem Leerzeichen umgeht

http://msdn.Microsoft.com/de-de/library/ms788746.aspx

Wenn Sie neugierig waren, warum eine Pause und eine Menge Tabs in ein einziges Leerzeichen übersetzt werden

Alle Leerzeichen (Leerzeichen, Zeilenvorschub, Tabulator) werden in .__ konvertiert. Leerzeichen.

Alle aufeinander folgenden Leerzeichen werden gelöscht und durch ein Leerzeichen ersetzt

110
Kevin DiTraglia

Eine weitere Option ist, den Abstand zwischen den Run-Tags zu kommentieren, den Code lesbar zu halten und den zusätzlichen Platz zu entfernen.

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

Ein Problem bei Kevins Nice-Lösung besteht darin, dass die einzeilige Formatierung von XAML-Tags rückgängig gemacht wird, wenn Sie einige der automatischen XAML/XML-Formatierungsfunktionen anwenden, z. "Strg-K + Strg-D". Eine Problemumgehung, die ich gefunden habe, ist das Formatieren der Run-Tags wie folgt:

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

Obwohl das Aufteilen des Tags über Zeilen wie dieses etwas unpraktisch ist, wird dieses Format nicht durch die automatische Neuformatierung geändert, vorausgesetzt, Sie wählen die Visual Studio-Option "Neue Zeilen und Leerzeichen zwischen Attributen beibehalten" für den XAML-Texteditor:

extra space eliminated between consecutive Run elements in XAML

15
Glenn Slayden

Meine Lösung ist, die Standardschriftgröße nahezu unsichtbar zu machen (FontSize="1") und dann die Schriftgröße bei jedem <Run auf die gewünschte Größe einzustellen: 

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

In Code Behind ist das besser möglich. Ich habe bisherige Lösungen ausprobiert, aber in bestimmten Situationen hat VS den sorgfältig eingerückten Code nur formatiert. 

1
Viktor Jasper

Ich habe eine angefügte Eigenschaft geschrieben, um dieses Verhalten zu umgehen.

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

Den gesamten Quellcode und die Erklärung dazu finden Sie hier . Wenn Sie diese angefügte Eigenschaft verwenden, können Sie die XAML-Formatierung so beibehalten, wie Sie möchten, aber diese Leerzeichen werden nicht in Ihrer gerenderten XAML angezeigt.

1
Pieter Nijs

Ich habe Pieter 's beigefügtes Eigentum zu WPF portiert (ich denke, es ist für UWP).

Beispiel:

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

 screenshot

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;
    }
}
0
Vimes