最近做一个项目需要用到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实现的效果相当的好:

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

  1. div中宽高度自适应文字换行居中问题解决

    <html> <head> <meta charset="UTF-8"/> <title>div中宽高度自适应文字换行居中demo& ...

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

    C# winform中 窗体缩放自适应的方法(不同电脑/不同分辨率)   窗体缩放是一个困扰我多时的问题,为了解决这个问题,我从网上找了很多相关的资料,很多人说用Anchor和Dock属性,但是我试了 ...

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

    win7中VS2010中安装CSS3.0问题解决方法   在安装Standards Update for VS2010 SP1后,VS2010中没有CSS3.0问题,以下是我的解决方法 1.首先去官网 ...

  4. winform中dataGridView高度自适应填充完数据的高度

    // winform中dataGridView高度自适应填充完数据的高度,就是dataGridView自身不产生滚动条,自己的高度是根据数据的多少而变动. 在load的时候,数据绑定后,加上如下代码: ...

  5. Div中高度自适应增长方法

    <html> <head> <meta http-equiv="Content-Type" content="text/html; char ...

  6. css实现div中图片高度自适应并与父级div宽度一致

    需求:1.父级div不设置高度 2.图片高度自适应,并且显示为正方形: 以前遇到列表中图片高度必须和父级宽度相同,并且需要为正方形的时候,最开始的方法是定死图片高度,这样会导致不同分辨率下图片会压缩, ...

  7. element table固定表头,表的高度自适应解决方法

    主要是通过在mounted生命周期中,改变tableHeight的值,来让表格的高度自适应. 标签: <el-table ref="table" :data="ta ...

  8. iframe高度自适应的方法

    第一种:iframe内容未知,高度可预测 这个时候,我们可以给它添加一个默认的CSS的min-height值,然后同时使用JavaScript改变高度.常用的兼容代码有: // document.do ...

  9. div中iframe高度自适应问题

    网页分为上.中.下三部分,上.下高度固定中间高度自适应:中间分为左.右两部分,左边宽度固定,右边宽度自适应.现在右侧div是宽度和高度都是自适应,右侧div里有个IFrame,想让IFrame自适应外 ...

随机推荐

  1. 到2023年将会有超过90%的PC采用SSD硬盘

    本文转载自超能网,其他媒体转载需经超能网同意 现在买电脑或者自己装机,还有谁不要SSD硬盘吗?这个问题似乎没什么可说的,SSD硬盘各种好,装机可以说是必选了,但实际上现在的SSD适配率并没有想象中那么 ...

  2. iotop---监控磁盘I/O 使用状况

    iotop命令是一个用来监视磁盘I/O使用状况的top类工具.iotop具有与top相似的UI,其中包括PID.用户.I/O.进程等相关信息.Linux下的IO统计工具如iostat,nmon等大多数 ...

  3. [USACO5.4]奶牛的电信Telecowmunication(网络流)

    P1345 [USACO5.4]奶牛的电信Telecowmunication 题目描述 农夫约翰的奶牛们喜欢通过电邮保持联系,于是她们建立了一个奶牛电脑网络,以便互相交流.这些机器用如下的方式发送电邮 ...

  4. 题解 P2872 【[USACO07DEC]道路建设Building Roads】

    这道题真的是令人窒息,Kruskal调了贼久一直RE,最后发现数组大小稍微少了那么一点点.(也就10倍吧..) 言归正传,根据本人的分析(以及算法标签的提示),这是一道求最小生成树的题目,当然要注意已 ...

  5. 读 Paxos 到 ZooKeeper ¥ 50大洋

    一  初识 ZooKeeper              高效且可靠的分布式协调服务.解决分布式一致性问题             统一命名服务.配置管理服务.分布式锁服务.      使用: 比如配 ...

  6. android动画-拖动

    先上图看效果 实质上说是动画有点不妥,确切的说应该是手势的处理,废话不多说看代码 SimpleDragSample.java public class SimpleDragSample extends ...

  7. 关于android studio几种常见的错误解决

    我也是从ec转到as的,没办法,大势所趋嘛,然而,在使用as的过程中遇到了非常多匪夷所思的错误,如今就说一下今天我遇到的这个错误. 美工妹子给了我一张图片,用来当做button的背景图,当然,这个图也 ...

  8. 特定位取反(js实现)

    去华为面试的时候.没有做好准备工作.面试的流程没有问清也没有查,结果一过去就让上机做题,着实有点措手不及.笔者是擅长前端的Java Webproject师啊,主要的底层编程知识早已生疏了.机试题碰到了 ...

  9. Task Scheduler

    https://technet.microsoft.com/en-us/library/cc748993(v=ws.11).aspx#BKMK_winui If Task Scheduler is n ...

  10. JSP脚本连接数据库

    入门 简单的jsp文件 <%-- Created by IntelliJ IDEA. User: e550 Date: 2017/1/9 Time: 23:24 To change this t ...