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

最新文章

  1. HTML5火焰文字特效DEMO演示
  2. @font-face 的用法
  3. 洛谷10月月赛Round.1| P3400 仓鼠窝[单调栈]
  4. Ext Js【Hello World】 ——4.1 beta 1
  5. My sql 日期格式化
  6. ArcGIS栅格数据的合并和剪切
  7. [leetcode]_Container With Most Water
  8. Zookeeper系列(二)特征及应用场景
  9. android新建项目时 出现appcompat_v7工程错误和红色感叹号
  10. 《转》VC++多线程编程
  11. Android:ViewPager详细解释(异步网络负载图片,有图片缓存,)并与导航点
  12. PhotonServer 学习
  13. 欢迎来到Devil_lixu的技术博客
  14. [bzoj1500][NOI2005]维修数列——splay
  15. Leetcode_80_Remove Duplicates from Sorted Array II
  16. 浅谈Python装饰器
  17. 在WSL中使用Window10中的virtualenv环境
  18. 软件工程项目之摄影App
  19. BZOJ3772精神污染——可持久化线段树+出栈入栈序
  20. 2012年蓝桥杯省赛A组c++第2题(暴力求解古堡算式)

热门文章

  1. 利用中间件 mysql_proxy 完成 mysql 的负载均衡和读写分离
  2. java源码学习
  3. Python内存分配器(如何产生一个对象的过程)
  4. LNMP安装部署开源IP管理工具phpipam
  5. Intel NUC迷你机2019年底迎来i9 8核心16线程
  6. Win10+TensorFlow-gpu pip方式安装,anaconda方式安装
  7. OpenGL 获取当前屏幕坐标对应的三维坐标
  8. Java.Lang.NoSuchMethod 错误
  9. android 在短信发送界面, 短信发送失败时,提示音不完整,会被中断
  10. 1.windows(64位)下使用curl命令