WPF中RichTextBox高度自适应问题解决方法

最近做一个项目需要用到RichTextBox来显示字符串,但是不允许出现滚动条,在RichTextBox宽度给定的条件下,RichTextBox的高度必须正好显示内容,而不出现下拉滚动条。

这样就要计算要显示的文本的高度,在网上找了许久,其中使用了FormattedText类来计算文本的高度,发现FormattedText计算出的高度总是比RichTextBox需要的高度小。

在网上找到,可自定义一个控件,继承System.Windows.Controls.RichTextBox。


private void AdjustHeight()
{
Rect rectStart = Document.ContentStart.GetCharacterRect(LogicalDirection.Forward);
Rect rectEnd = Document.ContentEnd.GetCharacterRect(LogicalDirection.Forward);
var height = rectEnd.Bottom - rectStart.Top;
var remainH = rectEnd.Height / 2.0;
var myHeight = Math.Min(MaxHeight, Math.Max(MinHeight, height + remainH));
this.Height = myHeight;

}

来计算Document的高度,但是在rectStart
,rectEnd 得到的值总是为Empty,没有办法来计算高度。后来发现只有在RichTextBox的IsArrangeValid值为True时,rectStart
、rectEnd 值才是有效的,必须放在

protected override void OnRender(DrawingContext drawingContext)
{
base.OnRender(drawingContext);
AdjustHeight();

}

这样才是有效的,但是包含这个自定义的RichTextBox的母控件必须是自定义的,按照如下重载MeasureOverride,ArrangeOverride方法,母控件对子控件进行二次测量、规划位置。重新对自定义的RichTextBox进行计算高度。


protected override Size MeasureOverride(Size availableSize)
{
Size panelDesiredSize = new Size();

foreach (UIElement child in InternalChildren)
{
child.Measure(availableSize);
panelDesiredSize = child.DesiredSize;
}

return panelDesiredSize;
}
protected override Size ArrangeOverride(Size finalSize)
{
foreach (UIElement child in InternalChildren)
{
double x = 10;
double y = 5;

child.Arrange(new Rect(new Point(x, y), child.DesiredSize));
}
return finalSize; // Returns the final Arranged size
}

这样实现的效果发现,UI运行比较慢。

后发现可以使用TextLine类来计算流文档的高度,关键代码如下:


public void Calculate()
{

var currentRendering = new FontRendering(
document.FontSize,
document.TextAlignment,
null,
document.Background,
new Typeface(document.FontFamily, document.FontStyle, document.FontWeight, document.FontStretch));

var textStore = new CustomTextSource();
textStore.Text = Content;
textStore.FontRendering = currentRendering;
var TextParagraphProperties = new GenericTextParagraphProperties(currentRendering);

System.Windows.Media.TextFormatting.TextFormatter
formatter = System.Windows.Media.TextFormatting.TextFormatter.Create();
TextLine myTextLine = null;
int startPoint = 0;
int RowCont = 0;
do
{
myTextLine = formatter.FormatLine(
textStore, startPoint, document.MinPageWidth, TextParagraphProperties, null);
//myTextLine.Draw(dc, new Point(0, RowCont * document.LineHeight), InvertAxes.None);
startPoint = startPoint + myTextLine.Length;
RowCont++;
} while (startPoint < Content.Length);
this.Height = Math.Max(RowCont * document.LineHeight, miniHight);
}

这个方法,可以在任何地方被正确的执行。一般可以在RichTextBox自定义控件的构造函数中调用,设定RichTextBox的高度。

关于TextLine 的使用,可以参考http://www.cnblogs.com/Clingingboy/archive/2010/12/03/1895326.html

最后RichTextBox实现的效果相当的好:

时间: 2024-11-05 00:18:47

WPF中RichTextBox高度自适应问题解决方法的相关文章

三种Div高度自适应的方法

让DIV高度自适应,这是在网页设计中常遇到的问题,为了给大家提供参考,这里提供3种div高度自适应的方法:一是JS法.二是背景图填充法.三是"补丁大法"(比较变态). 1.JS法 代码如下.原理:用JS判断左右DIV的高度,若不一致则设为一致.框架资源分享 Java代码   <div style="width:500px;background:#cccccc;height:0px;"> <div id="right" style

win7中VS2010中安装CSS3.0问题解决方法

win7中VS2010中安装CSS3.0问题解决方法 在安装Standards Update for VS2010 SP1后,VS2010中没有CSS3.0问题,以下是我的解决方法 1.首先去官网下载 CSS 3 Intellisense Schema 网址:http://visualstudiogallery.msdn.microsoft.com/7211bcac-091b-4a32-be2d-e797be0db210/view/Discussions/1 2.安装 3.Win+R 输入 re

Android中ListVIew高度自适应,解决ScrollView冲突问题以及Android表格

效果图 类似格式, listView_item.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="ma

div中iframe高度自适应问题

网页分为上.中.下三部分,上.下高度固定中间高度自适应:中间分为左.右两部分,左边宽度固定,右边宽度自适应.现在右侧div是宽度和高度都是自适应,右侧div里有个IFrame,想让IFrame自适应外部div的宽度和高度? 我自己做的时候出现的问题是:当ifame的width和height设置为100%时,iframe会被挤出div,下滑到div的下面.然后我试了很多网上说的也没有解决,然后加了个东西就不会出现那种情况了 下面为我的div的js设置 //window.onresize表示窗口触发

html5图片高度自适应解决方法

今天遇到一个HTML5图片高度自适应各个设备问题,网上找到一个解决方法,跟大家分享下. 由于<body>标签的图片不能够拉伸, 解决办法: 1.图片不够大,又background属性不能拉伸图片: 2.只能用个div,把其z-index值设为负,并使这个div大小为整个body大小,在div里用<img> 3.body的background属性去掉,要不然会被遮住. <!DOCTYPE HTML> <html> <head> <meta c

在WPF中使用WinForm控件方法

1.      首先添加对如下两个dll文件的引用:WindowsFormsIntegration.dll,System.Windows.Forms.dll. 2.      在要使用WinForm控件的WPF窗体的XAML文件中添加如下内容: 即: xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms" xmlns:wfi ="clr-namespace:System.Windo

网页图片宽度和高度自适应的方法

在我们设计网页的时候,经常会遇到图片自适应问题,实际这些工作完全可以交给浏览器来完成就可以了,只可惜,无论是IE还是FIREFOX在图片自适应这个问题上都处理的不尽人意,网上实现网页图片宽度和高度的方法也很多,主要又两种: 第一种是使用CSS来完成:第二种是使用Javascript来完成,根据实际的应用效果来说,使用Javascript还是比较靠谱一点,因为CSS的expression的确有点烦,笔者是指使用效果上有点恼人,本文专门把这两种都总结一下,方便站长们参考使用. 一.使用CSS实现图片

C# winform中 窗体缩放自适应的方法(不同电脑/不同分辨率)

窗体缩放是一个困扰我多时的问题,为了解决这个问题,我从网上找了很多相关的资料,很多人说用Anchor和Dock属性,但是我试了以后,始终不能达到想要的效果. 后来,搜到了一个帖子,终于解决了这个问题,再次对该贴作者表示感谢.原帖链接为: http://www.cnblogs.com/sydeveloper/archive/2013/01/29/2881521.html 以下是笔者的实现过程: 1.  首先在窗体上放上一个Panel容器,并将容器的Dock属性设为Fill,即所有的控件都放在了这个

linux 环境下安装oracle11g方法及安装过程中遇上的问题解决方法

 Oralce安装教程 1.先安装需要的依赖包 找到哪个没有安装,直接yum install XX,直到所有的都安装完成.注意,可能一个包安装了,再次执行检查,还是提示没有安装,那么就不需要管他们了,继续安装下面的. rpm -q binutils compat-libstdc++ elfutils-libelf elfutils-libelf-devel elfutils-libelf-devel-static gcc gcc-c++ glibc glibc-common glibc-deve