c# - WPF:如何使 RichTextBox 看起来像 TextBlock?

标签 c# .net wpf richtextbox padding

我怎样才能制作RichTextBox没有边距、边框、填充等?换句话说,以与 TextBlock 相同的方式显示内容可以 ?我试过这个:

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

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

enter image description here

文档内容之前还有一些空间(可能之后,在文档的顶部或底部...)。我怎样才能删除它?


如果你对我为什么需要这个感兴趣:我试图制作 H.B.'s answer我的问题Create guitar chords editor in WPFkerning一起工作我不想在字符之间有不自然的空间。


编辑

所以它不是 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

按照 Daniel Rose 在他的 las edit 中建议的那样添加双向绑定(bind)后,它就可以工作了。仍然我真的不认为它很清楚(具有依赖属性,因为我需要将 PagePadding 保持在 0 值)。 我认为这是一个 hack - bug workaround。 如果有人有更好的解决方案,请分享。

显然,将 FlowDocument 的“PagePadding”更改为 0,5 是一个错误。如果有人拥有 MSDN 帐户,如果他们报告此错误,那就太好了。

最佳答案

我知道这很烦人。

RichTextBox 在它的 CreateRenderScope() 中设置此 PagePadding,即当它附加到可视化树时。此时所有属性通常都已设置,因此 PagePadding 会被重置。

我将要向您展示的是一种更通用的形式,说明如何使用附加属性执行此操作。在我自己的代码中,我通常会更严格地执行此操作,因为我知道 a) flowdocument 不会更改(不必担心两次注册相同的处理程序)和 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

关于c# - WPF:如何使 RichTextBox 看起来像 TextBlock?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5820578/

相关文章:

c# - 如果 MVVM 模型继承扩展到所有选项卡,为什么 Treeview 会扩展?

c# - 限制 ItemsControl 的子项的编译时类型

c# - 无法在 VS 2017 U1 (15.3) 中打开的项目上加载类型 'Microsoft.Build.Framework.SdkReference'

C# MySql 错误 : An established connection was aborted by the software in your host machine

c# - 如何使用响应式扩展实现 'handle remaining' 观察者

wpf - 将鼠标事件传递给重叠控件

C# 快速折线图

c# - 无法通过 CaSTLe Windsor 传递通用参数

c# - 从 TaskCompletionSource 返回 Task 而不是 Task<TResult>

wpf - 我如何松散地引用 Prism 中的模块,以便它们可以存在或不存在?