最近做一个项目需要用到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. vuex 闲置状态重置方案

    前言 大型单页应用(后面都是指spa),我们往往会通过使用状态管理器 vuex 去解决组件间状态共享与状态传递等问题.这种应用少则几十个单页,多则上百个单页.随着路由的频繁切换,每个路由对应的 vue ...

  2. WHU 1542 Countries (floyd)

    题意: 在小明出生的星球X上有n国家. 一些国家通过结盟而拥有良好的双边关系,因此他们的公民得益于这些政策,使得所有这些国家之间的旅行变得免费. 但是,不同联盟之间的旅行就不是这么容易了.如果可能,它 ...

  3. Java代码规范文档

    NOTE:以下部分为一个简要的编码规范,更多规范请参考 ORACLE 官方文档. 地址:http://www.oracle.com/technetwork/java/codeconventions-1 ...

  4. 【转】 HtmlAgilityPack使用——XPath注意事项

    [转] HtmlAgilityPack使用——XPath注意事项 在使用HtmlAgilityPack这个开源的类库进行网页内容解析的时候是非常的方便(使用方法见另一篇博客<HTML解析:基于X ...

  5. 3D打印技术之切片引擎(6)

    [此系列文章基于熔融沉积( fused depostion modeling, FDM )成形工艺] 这一篇文章说一下填充算法中的网格填充.网格填充在现有的较为成熟的引擎中是非常普遍的:skeinfo ...

  6. JsonRequestBehavior.AllowGet 方便浏览器调试

    [HttpGet] public ActionResult getCoversationList(int CustomerId) { // 获取用户相关的聊天数据,包括个人,群,系统(可以单独获取) ...

  7. ZOJ 2588 Burning Bridges(求桥的数量,邻接表)

    题目地址:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2588 Burning Bridges Time Limit: 5 ...

  8. 19.volatile

    volatile 编译器会自动优化,而volatile起到的作用是禁止优化,每次读内存

  9. SQL函数-stuff()

    select stuff(列名,开始位置,长度,替代字符串) 用于删除指定长度的字符串,并可以在指定长度的地方插入新的字符: 在指定长度的地方添加新的字符

  10. WebAssembly学习(五):AssemblyScript - Hello World

    一.项目创建 1.创建AssemblyScript根目录 mkdir AssemblyScript 2.安装AssemblyScript开发依赖 cnpm install --save-dev Ass ...