最近做一个项目需要用到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. caffe(7) solver及其配置

    solver算是caffe的核心的核心,它协调着整个模型的运作.caffe程序运行必带的一个参数就是solver配置文件.运行代码一般为 # caffe train --solver=*_slover ...

  2. bzoj5085: 最大 暴力 二分

    Code: #include<cstdio> #include<algorithm> #include<cstring> #include<iostream& ...

  3. lhgDialog使用--loading提示(不自动关闭)

    使用lhgDialog时,发现有一个$.dialog.tips()方法可以实现loading样式的提示,但是存在默认关闭时间.方法如下图所示, 为了实现不自动关闭的方法,查看了相应的源码后,实现不关闭 ...

  4. java开发微信公众号支付(JSAPI)

    https://www.cnblogs.com/gopark/p/9394951.html,这篇文章写的已经很详细了. 下面写一下自己的思路: 1.首先下载demo,地址:https://pay.we ...

  5. 安卓ContentObserver模式获取短信用正则自己主动填充验证码

    近期做注冊的时候看到非常多app在手机接受到短信的时候直接填写验证码到界面省略用户自己主动输入,感觉这样确实蛮人性化的呵呵.于是自己也做了一个 步骤: 首先我使用了ContentObserver监听短 ...

  6. swift学习之数组

    首先数组的定义:以有序的方式存储同样类型的值 (1)数组的简写(shorthand)语法 你能够通过Array<Element>,在这里,Element时数组存储元素的值的类型.也能够通过 ...

  7. EBS TimeZone问题

    记录问题 :  http://blog.csdn.net/cymm_liu/article/details/29234919     --     Oracle 数据库中的 时间 时区 http:// ...

  8. Magento--修改已存在的订单的运费

    遇到一种情况,需要在下单后再由管理员添加订单运费,然后顾客再付款.那么问题来了,如何给订单添加运费呢?下面是一段代码,可以实现该功能: $orderId = 'your order id';$orde ...

  9. SQL Server 2000数据库备份与恢复图解

    SQL Server 2000数据库备份与恢复图解   四个步骤:1.安装sql server 2000 2.数据库设置: 3.建立自动备份 4.还原数据库  具体图片见附件 本文出自 "李 ...

  10. 打包,VS 之 InstallShield Limited Edition for Visual Studio 2015 图文教程

    转载收藏于 https://www.cnblogs.com/xinaixia/p/5473815.html 从Visual Studio 2012开始,微软就把自家原来的安装与部署工具彻底废掉了,转而 ...