4

我正在尝试使用 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;
4

2 回答 2

6

假设你有一个非常基本RichTextBox的标准FlowDocument,那么你必须考虑所有额外的布局RichTextBox使用。

Document.PagePadding属性默认为{5,0,5,0}。所以你必须在宽度上加 10。

此外,RichTextBox还有一个BorderThickness默认为{1, 1, 1, 1}. 所以你必须在宽度上加 2。

所以你想要的代码可能看起来像:

var pagePadding = rtb.Document.PagePadding;
var borderThickness = rtb.BorderThickness;
rtb.Width = formattedText.Width
    + pagePadding.Left + pagePadding.Right 
    + borderThickness.Left + borderThickness.Right;

如果你这样做,你仍然会偏离 1 个字符,但这有点误导。RichTextBox即使文本只是一点点宽而不是整个字符宽度,它也会换行。如果你在宽度上加上 2 就可以了。我无法弄清楚额外 2 的确切来源。我从来没有试图让宽度如此精确。我之前遇到过PagePaddingandBorderThickness问题,但我找不到额外的 2。这可能只是你坚持的常数,但我对此表示怀疑。它一定在某个地方。

关于制作StandardizationLine你可以做的小技巧

string StandardizationLine = new string('X', columns);

清理循环。

于 2010-04-03T13:23:54.637 回答
0

我找到了富文本框高度问题的解决方案..我已将其修改为一般用途..

在您的应用程序中创建以下结构......

[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...

于 2012-02-23T14:45:25.873 回答