Einstellen WPF RichTextBox Breite und Höhe entsprechend der Größe einer nichtproportionalen Schrift

StackOverflow https://stackoverflow.com/questions/2569191

  •  24-09-2019
  •  | 
  •  

Frage

Ich versuche, eine WPF RichTextBox passe ein Raster von Zeichen in einem bestimmten nichtproportionalen Schrift genau anzupassen. Ich bin derzeit FormattedText mit der Breite und Höhe meines RichTextBox, um zu bestimmen, aber die Messungen es mich bietet mit zu klein sind -. Insbesondere zwei Zeichen in der Breite zu klein

Gibt es einen besseren Weg, um diese Aufgabe zu erfüllen? Dies scheint nicht ein geeigneter Weg zu sein, um die Größe meiner Kontrolle zu bestimmen.

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;
War es hilfreich?

Lösung

Sie haben Angenommen, ein sehr einfaches RichTextBox nur mit dem Standard FlowDocument im Inneren, dann müssen Sie berücksichtigen alle zusätzlichen Layout RichTextBox Anwendungen.

Die Document.PagePadding Eigenschaft standardmäßig auf {5,0,5,0}. So werden Sie haben 10 die Breite hinzuzufügen.

Darüber hinaus hat die RichTextBox eine BorderThickness, dass standardmäßig {1, 1, 1, 1}. Sie werden also 2 die Breite hinzuzufügen haben.

So ist der Code, den Sie sich wünschen könnte wie folgt aussehen:

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

Wenn Sie tun, dass Sie immer noch von 1 Zeichen aus sein werden, aber das ist eine irreführende Bit. Die RichTextBox wird wickeln, auch wenn der Text nur ein kleines bisschen zu breit nicht nur eine ganze Zeichenbreite. Wenn Sie 2 auf die Breite hinzufügen klappt es. Ich kann nicht genau herausfinden, wo die zusätzlichen 2 herkommt. Ich habe noch nie so genau zu bekommen, die Breite zu sein versucht. Ich habe, bevor sie in den PagePadding und BorderThickness Probleme laufen, aber ich kann einfach nicht finden die zusätzlichen 2. Es könnte nur eine Konstante sein, das Sie mit stecken, aber ich bezweifle es. Es muss irgendwo sein.

Eine kleine Spitze der StandardizationLine auf die Herstellung Sie tun können,

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

, um die Schleife zu bereinigen.

Andere Tipps

ich eine Lösung für die Rich-Text-Boxhöhe Probleme gefunden .. Ich habe es eine für den allgemeinen Gebrauch modifiziert ..

Erstellen Sie folgende Strukturen in Ihrer Anwendung ....

[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;
    }

Erstellen Sie folgende private Variablen in der Klasse für Form (wo immer Sie Rich-Text-Höhe berechnen müssen)

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);

Fügen Sie folgende Methode Ihrer Klasse für Form

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;
        }

Sie müssen über Verfahren ändern, um es wie pro Ihre Anforderung funktioniert ... Stellen Sie sicher, Rtf String als Parameter Methode nicht normalen Text und auch sicherstellen, dass zu assign verfügbarer Breite und Höhe auf den RichTextBox Variable in der Methode ...

senden

Sie können mit WordWrap je nach Anforderung spielen ...

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top