我正在尝试使用WPF RichTextBox来精确地容纳特定等宽字体中的字符网格。我目前正在使用FormattedText来确定我的RichTextBox的宽度和高度,但它为我提供的测量值太小 - 特别是宽度太小的两个字符。
有没有更好的方法来执行此任务?这似乎不是确定我的控件大小的合适方法。
RichTextBox rtb;
rtb = new RichTextBox();
FontFamily fontFamily = new FontFamily("Consolas");
double fontSize = 16;
char standardizationCharacter = 'X';
String standardizationLine = "";
for(long loop = 0; loop < columns; loop ++) {
standardizationLine += standardizationCharacter;
}
standardizationLine += Environment.NewLine;
String standardizationString = "";
for(long loop = 0; loop < rows; loop ++) {
standardizationString += standardizationLine;
}
Typeface typeface = new Typeface(fontFamily, FontStyles.Normal, FontWeights.Normal, FontStretches.Normal);
FormattedText formattedText = new FormattedText(standardizationString, CultureInfo.CurrentCulture, FlowDirection.LeftToRight, typeface, fontSize, Brushes.Black);
rtb.Width = formattedText.Width;
rtb.Height = formattedText.Height;
答案 0 :(得分:6)
假设您有一个非常基本的RichTextBox
,其中只有标准的FlowDocument
,那么您必须考虑所有额外的布局RichTextBox
用途。
Document.PagePadding
属性默认为{5,0,5,0}
。所以你必须在宽度上加10。
此外,RichTextBox
的{{1}}默认为BorderThickness
。所以你必须在宽度上加2。
所以你想要的代码看起来像:
{1, 1, 1, 1}
如果你这样做,你仍会被1个角色所禁止,但这有点误导。 var pagePadding = rtb.Document.PagePadding;
var borderThickness = rtb.BorderThickness;
rtb.Width = formattedText.Width
+ pagePadding.Left + pagePadding.Right
+ borderThickness.Left + borderThickness.Right;
将换行,即使文本只是一小部分而不是整个字符宽度。如果你在宽度上添加2就可以了。我无法确切知道额外的2来自哪里。我从未试图让宽度如此精确。我之前遇到过RichTextBox
和PagePadding
问题,但我找不到额外的2.它可能只是一个常数,你被困住了,但我对此表示怀疑。它必须在某个地方。
关于制作BorderThickness
你可以做的小提示
StandardizationLine
清理循环。
答案 1 :(得分:0)
我找到了Rich文本框高度问题的解决方案..我已将其修改为一般用途..
在您的应用程序中创建以下结构....
[StructLayout(LayoutKind.Sequential)]
public struct RECT {
public Int32 left;
public Int32 top;
public Int32 right;
public Int32 bottom;
}
[StructLayout(LayoutKind.Sequential)]
public struct SCROLLBARINFO {
public Int32 cbSize;
public RECT rcScrollBar;
public Int32 dxyLineButton;
public Int32 xyThumbTop;
public Int32 xyThumbBottom;
public Int32 reserved;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
public Int32[] rgstate;
}
在您的类中为表单创建以下私有变量(您需要计算富文本高度)
private UInt32 SB_VERT = 1;
private UInt32 OBJID_VSCROLL = 0xFFFFFFFB;
[DllImport("user32.dll")]
private static extern
Int32 GetScrollRange(IntPtr hWnd, UInt32 nBar, out Int32 lpMinPos, out Int32 lpMaxPos);
[DllImport("user32.dll")]
private static extern
Int32 GetScrollBarInfo(IntPtr hWnd, UInt32 idObject, ref SCROLLBARINFO psbi);
将以下方法添加到您的课程表格
private int CalculateRichTextHeight(string richText) {
int height = 0;
RichTextBox richTextBox = new RichTextBox();
richTextBox.Rtf = richText;
richTextBox.Height = this.Bounds.Height;
richTextBox.Width = this.Bounds.Width;
richTextBox.WordWrap = false;
int nHeight = 0;
int nMin = 0, nMax = 0;
SCROLLBARINFO psbi = new SCROLLBARINFO();
psbi.cbSize = Marshal.SizeOf(psbi);
richTextBox.Height = 10;
richTextBox.ScrollBars = RichTextBoxScrollBars.Vertical;
int nResult = GetScrollBarInfo(richTextBox.Handle, OBJID_VSCROLL, ref psbi);
if (psbi.rgstate[0] == 0) {
GetScrollRange(richTextBox.Handle, SB_VERT, out nMin, out nMax);
height = (nMax - nMin);
}
return height;
}
您可能需要修改上述方法,使其按照您的要求运行... 确保将Rtf字符串作为参数发送到方法而不是普通文本,并确保为方法中的Richtextbox变量指定可用的宽度和高度...
您可以根据需要使用WordWrap ...