如何删除空段落占用的空间?

时间:2015-06-16 19:44:03

标签: wpf xaml paragraph

如何摆脱段落中的空间?我尝试使用否定margin/padding,但它不接受这些属性的负值。有什么想法吗?

我的代码如下:

<FlowDocument>
    <Section>
        <Paragraph>1</Paragraph>
        <Paragraph>2</Paragraph>
        <Paragraph></Paragraph>
        <Paragraph>4</Paragraph>
    </Section>
</FlowDocument>

并且,上面代码的输出如下:

enter image description here

编辑:这是一个更有意义的例子(根据评论):

<FlowDocument>
    <Section>
        <Paragraph>
            <TextBlock Text="1" Visibility="Visible"/>
        </Paragraph>
        <Paragraph>
            <TextBlock Text="2" Visibility="Visible"/>
        </Paragraph>
        <Paragraph>
            <TextBlock Text="3" Visibility="Collapsed"/>
        </Paragraph>
        <Paragraph>
            <TextBlock Text="4" Visibility="Visible"/>
        </Paragraph>
    </Section>
</FlowDocument>

结果完全相同。

4 个答案:

答案 0 :(得分:4)

我毫不犹豫地发布这个,因为我确信必须有更好的方法,但是因为没有其他人回复过....

流文档Section似乎用段落的LineHeight包含空格等于段落的段落。

LineHeight不能为0,但它可能非常小。在LineHeight上设置Section将删除所有段落周围的空格。

<FlowDocumentScrollViewer>
    <FlowDocumentScrollViewer.Resources>
        <Style TargetType="Paragraph">
            <Setter Property="Background" Value="LightBlue" />
        </Style>
    </FlowDocumentScrollViewer.Resources>

    <FlowDocument>
        <Section LineHeight="0.1">
            <Paragraph>1</Paragraph>
            <Paragraph>2</Paragraph>
            <Paragraph/>                       
            <Paragraph>4</Paragraph>
            <Paragraph>5</Paragraph>
        </Section>
    </FlowDocument>

</FlowDocumentScrollViewer>

像这样设置LineHeight通常不会影响段落中的文本,因为默认的LineStackingStrategy会使用字体的高度。请注意空白段落的高度如何。

您可能认为仅在空白段落上设置LineHeight会起作用,但Section仍会尊重前一段落的空格。由于前一段具有正常LineHeight,您仍然可以获得保证金。

因此,为了完全删除空白段落,您需要在空白段和前段落上设置LineHeight,并告诉空白段落使用LineHeight作为块高度:< / p>

<FlowDocumentScrollViewer>
    <FlowDocumentScrollViewer.Resources>
        <Style TargetType="Paragraph">
            <Setter Property="Background" Value="LightBlue" />
        </Style>
    </FlowDocumentScrollViewer.Resources>

    <FlowDocument>
        <Section>
            <Paragraph>1</Paragraph>
            <Paragraph LineHeight="0.1">2</Paragraph>
            <Paragraph LineHeight="0.1" LineStackingStrategy="BlockLineHeight"/>                       
            <Paragraph>4</Paragraph>
            <Paragraph>5</Paragraph>
        </Section>
    </FlowDocument>

</FlowDocumentScrollViewer>

我尝试编写一个触发器,它会自动为空白段落执行此操作,但不幸的是Paragraph.Inlines.Count不是DependencyProperty,并且尝试使用它来检测空白段落是不可靠的,具体取决于段落的填充时间。< / p>

答案 1 :(得分:2)

如果在您的方案中可行的VM属性指示段落是否为空,那么这将起作用: -

<FlowDocument>
  <FlowDocument.Resources>
    <Style TargetType="{x:Type Paragraph}">
      <Setter Property="Margin" Value="0,0,0,18"/>
      <Style.Triggers>
        <Trigger Property="Tag" Value="True">
           <Setter Property="Margin" Value="0"/>
           <Setter Property="LineHeight" Value="0.1"/>
           <Setter Property="LineStackingStrategy" Value="BlockLineHeight"/>
        </Trigger>
      </Style.Triggers>
    </Style>
  </FlowDocument.Resources>
  <Section>
     <Paragraph x:Name="p1" Tag="{Binding IsPara1Empty}">1</Paragraph>
     <Paragraph x:Name="p2" Tag="{Binding IsPara2Empty}">2</Paragraph>
     <Paragraph x:Name="p3" Tag="{Binding IsPara3Empty}"></Paragraph>
     <Paragraph x:Name="p4" Tag="{Binding IsPara4Empty}">4</Paragraph>
  </Section>
</FlowDocument>

根据您的字体大小,您可能需要使用样式&#34;默认&#34;保证金价值为&#34; 0,0,0,18&#34;。

或者,如果可以通过编程方式确定段落是否为空,则可以创建一个公开Paragraph依赖项属性的继承IsEmpty控件。触发器将使用此而不是Tag,您将不需要VM属性。

答案 2 :(得分:1)

试试这个

<FlowDocument>

            <Section>

                <Paragraph>
                   1
                </Paragraph>
                <Paragraph>
                    2
                </Paragraph>
                <Paragraph local:AttachNew.MyProperty="1">

                </Paragraph>

                    <Paragraph>
                    4
                </Paragraph>
            </Section>
        </FlowDocument>

public class AttachNew
    {
        public static int GetMyProperty(DependencyObject obj)
        {
            return (int)obj.GetValue(MyPropertyProperty);
        }

        public static void SetMyProperty(DependencyObject obj, int value)
        {
            obj.SetValue(MyPropertyProperty, value);
        }

        // Using a DependencyProperty as the backing store for MyProperty.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty MyPropertyProperty =
            DependencyProperty.RegisterAttached("MyProperty", typeof(int), typeof(AttachNew), new PropertyMetadata(0, new PropertyChangedCallback(ChangeProp)));

        private static void ChangeProp(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            Section objparent = (d as System.Windows.Documents.Paragraph).Parent as Section;
            objparent.Blocks.Remove((d as System.Windows.Documents.Paragraph));
        }
    }

答案 3 :(得分:1)

在HTML中,段落标记(即使是空的)占用空间的原因是因为它是块级元素,因此它是hasLayout。这意味着它具有渲染代理为其指定的填充和行高等属性,以及它将导致换行

您能找到一种方法来检测段落是否为空并更改其显示规则吗?可见性不会删除元素,只会使其不可见,因此段落标记仍会导致令人讨厌的换行符。实际上,之前发布的行高解决方案仍然留在换行符中。 (An article about display vs visibility.

可以使用CSS规则display:none;将其从页面流中删除(请参阅上面的hasLayout链接)。我喜欢使用CSS类并以编程方式应用它。这样的事情通常会起到作用:

.hidden {display:none;height:0;width:0;}

您还可以在该课程中加入line-height:0;以涵盖之前的建议。