WPF中RichTextBox高度自适应问题解决方法
2024-08-31 11:26:13
最近做一个项目需要用到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实现的效果相当的好:
最新文章
- HTML5火焰文字特效DEMO演示
- @font-face 的用法
- 洛谷10月月赛Round.1| P3400 仓鼠窝[单调栈]
- Ext Js【Hello World】 ——4.1 beta 1
- My sql 日期格式化
- ArcGIS栅格数据的合并和剪切
- [leetcode]_Container With Most Water
- Zookeeper系列(二)特征及应用场景
- android新建项目时 出现appcompat_v7工程错误和红色感叹号
- 《转》VC++多线程编程
- Android:ViewPager详细解释(异步网络负载图片,有图片缓存,)并与导航点
- PhotonServer 学习
- 欢迎来到Devil_lixu的技术博客
- [bzoj1500][NOI2005]维修数列——splay
- Leetcode_80_Remove Duplicates from Sorted Array II
- 浅谈Python装饰器
- 在WSL中使用Window10中的virtualenv环境
- 软件工程项目之摄影App
- BZOJ3772精神污染——可持久化线段树+出栈入栈序
- 2012年蓝桥杯省赛A组c++第2题(暴力求解古堡算式)
热门文章
- 利用中间件 mysql_proxy 完成 mysql 的负载均衡和读写分离
- java源码学习
- Python内存分配器(如何产生一个对象的过程)
- LNMP安装部署开源IP管理工具phpipam
- Intel NUC迷你机2019年底迎来i9 8核心16线程
- Win10+TensorFlow-gpu pip方式安装,anaconda方式安装
- OpenGL 获取当前屏幕坐标对应的三维坐标
- Java.Lang.NoSuchMethod 错误
- android 在短信发送界面, 短信发送失败时,提示音不完整,会被中断
- 1.windows(64位)下使用curl命令