I have following XAML:
I've written a Attached Property to 'bypass' this behavior.
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));
}
}
The entire source code and the explanation of it all can be found here. By using this attached property you can keep your XAML formatting just the way you want, but you don't get these whitespaces in your rendered XAML.