我如何制作没有边距,边框,填充等的 RichTextBox ?换句话说,以与 TextBlock 相同的方式显示内容吗?我已经试过了:

<RichTextBox Margin="0" Padding="0" Grid.Row="0" BorderThickness="0" >
    <FlowDocument >
        <Paragraph>LLL</Paragraph>
    </FlowDocument>
</RichTextBox>
<TextBlock>LLL</TextBlock>

但是结果产生的仍然不是我想要的:

文档内容之前(以及文档顶部或底部之后的位置)还有一些空间。如何删除它?

如果您有兴趣,为什么我需要这样做:我尝试将H.B.'s answer设置为我的问题Create guitar chords editor in WPF以与kerning一起使用,并且我不想字符之间有不自然的间隔。

编辑

因此,不仅仅ControlTemplate不仅因为以下代码将产生完全相同的结果(与上图中的结果相同):
<RichTextBox Margin="0" Padding="0" Grid.Row="0" BorderThickness="0">
    <RichTextBox.Template>
        <ControlTemplate>
            <ScrollViewer Padding="0" Margin="0" x:Name="PART_ContentHost"/>
        </ControlTemplate>
    </RichTextBox.Template>
    <FlowDocument PagePadding="0">
        <Paragraph Padding="0" Margin="0" >LLL</Paragraph>
    </FlowDocument>
</RichTextBox>

而且我认为这将是个容易回答的问题... 有趣的观察:设置模板并在PagePadding="0" 上设置FlowDocument时,它会在VisualStudio设计器中显示我想要的布局-,直到运行演示。在演示中,这又是错误的...当我关闭演示时,在设计器中又是错误的。这是VS的一个小错误,还是实际上是将其设置为正确的布局一段时间,然后又将PagePadding的值改回了错误的值?

编辑#2

Daniel Rose编辑的答案对我也不起作用。这是XAML:
<FlowDocument PagePadding="{Binding PagePadding}">
    <Paragraph x:Name="paragraph" Padding="0"
        TextIndent="0"  Margin="0,0,0,0" >hello</Paragraph>
</FlowDocument>

这是在代码中:
public static DependencyProperty PagePaddingProperty =
            DependencyProperty.Register("PagePadding", typeof(Thickness),   typeof(EditableTextBlock),
            new PropertyMetadata(new Thickness(0)));

public Thickness PagePadding {
    get { return (Thickness)GetValue(PagePaddingProperty); }
    set { SetValue(PagePaddingProperty, value); }
}

无需更改结果。空间仍然存在。

编辑#3

在添加双向绑定(bind)后,如丹尼尔·罗斯(Daniel Rose)在他的文档编辑中建议的那样,它可以工作。仍然我不太清楚(拥有依赖属性,因为我需要将PagePadding保持在0值)。 我认为这是一种破解-错误的解决方法。 如果有人有更好的解决方案,请分享。

显然,将PagePaddingFlowDocument更改为0,5是一个错误。如果有人拥有MSDN帐户,则报告他们的错误将是很好的。

最佳答案

我知道这很烦人。
RichTextBox在它的CreateRenderScope()中设置此PagePadding,即当它附加到可视树时。此时,通常已经设置了所有属性,因此PagePadding被重置。

我将向您展示的是一种更一般的形式,说明如何使用附加属性来执行此操作。在我自己的代码中,我通常会更严格地执行此操作,因为我知道a)流文档不会更改(不必担心两次注册同一处理程序),并且b)填充不会更改(事件处理程序只是((FlowDocument)s).PagePadding = new Thickness(0.0);)。这样,尽管我将提供一个通用的解决方案,您只需插入即可。

解决方案:

        <RichTextBox BorderThickness="0" Margin="0" Padding="0">
            <FlowDocument local:FlowDocumentPagePadding.PagePadding="0">
                <Paragraph>
                    <Run>text</Run>
                </Paragraph>
            </FlowDocument>
        </RichTextBox>
public static class FlowDocumentPagePadding
{
    public static Thickness GetPagePadding(DependencyObject obj)
    {
        return (Thickness)obj.GetValue(PagePaddingProperty);
    }
    public static void SetPagePadding(DependencyObject obj, Thickness value)
    {
        obj.SetValue(PagePaddingProperty, value);
    }
    public static readonly DependencyProperty PagePaddingProperty =
        DependencyProperty.RegisterAttached("PagePadding", typeof(Thickness), typeof(FlowDocumentPagePadding), new UIPropertyMetadata(new Thickness(double.NegativeInfinity),(o, args) =>
            {
                var fd = o as FlowDocument;
                if (fd == null) return;
                var dpd = DependencyPropertyDescriptor.FromProperty(FlowDocument.PagePaddingProperty, typeof(FlowDocument));
                dpd.RemoveValueChanged(fd, PaddingChanged);
                fd.PagePadding = (Thickness) args.NewValue;
                dpd.AddValueChanged(fd, PaddingChanged);
            }));
    public static void PaddingChanged(object s, EventArgs e)
    {
        ((FlowDocument)s).PagePadding = GetPagePadding((DependencyObject)s);
    }
}

原始源代码注释:

RichTextBox.CreateRenderScope()的原始来源中,开发人员包括以下注释:
// Set a margin so that the BiDi Or Italic caret has room to render at the edges of content.
// Otherwise, anti-aliasing or italic causes the caret to be partially clipped.
renderScope.Document.PagePadding = new Thickness(CaretElement.CaretPaddingWidth, 0, CaretElement.CaretPaddingWidth, 0);

错误报告

here is the bug report on Microsoft Connect

10-03 00:52