我怎样才能制作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>
我认为这个问题很容易回答...有趣的观察:当我设置了模板并在 上设置了
它在 VisualStudio 设计器中显示我想要的布局 - 直到我运行演示。在演示中它又错了......当我关闭演示时它在设计器中又错了。这是 VS 的一个小错误,还是它实际上设置了一段时间的正确布局,但随后某些东西将 PagePadding="0"
FlowDocumentPagePadding
的值更改回了一些错误的值?
编辑#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);
错误报告
关于c# - WPF:如何使 RichTextBox 看起来像 TextBlock?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5820578/