تعيين WPF RichTextbox عرض وارتفاع وفقًا لحجم خط Monospace

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

  •  24-09-2019
  •  | 
  •  

سؤال

أحاول أن أتناسب مع WPF RichTextBox لاستيعاب شبكة من الشخصيات في خط Monospace معين. أنا أستخدم حاليًا FormattedText لتحديد عرض وارتفاع صندوق RichText ، لكن القياسات التي توفرها لي صغيرة جدًا-على وجه التحديد ، عرضان في العرض صغير جدًا.

هل هناك طريقة أفضل لأداء هذه المهمة؟ لا يبدو أن هذا وسيلة مناسبة لتحديد حجم سيطرتي.

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;
هل كانت مفيدة؟

المحلول

على افتراض أن لديك أساسية للغاية 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;

إذا قمت بذلك ، فستظل ستواجه شخصية واحدة ، لكن هذا مضللة بعض الشيء. ال RichTextBox سوف يلف حتى لو كان النص مجرد القليل إلى واسع وليس مجرد عرض حرف كامل. إذا قمت بإضافة 2 إلى العرض ، فهي تعمل. لا يمكنني معرفة بالضبط من أين يأتي هذا الإضافي 2. لم أحاول أبدًا الحصول على العرض ليكون دقيقًا للغاية. لقد واجهت PagePadding و BorderThickness المشكلات من قبل ، لكنني لا أستطيع العثور على الإضافية 2. قد يكون الأمر ثابتًا تمامًا ، لكنني أشك في ذلك. يجب أن يكون في مكان ما.

نصيحة صغيرة على إنتاج StandardizationLine يمكنك ان تفعل

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

لتنظيف الحلقة.

نصائح أخرى

لقد وجدت حلاً لمشكلات ارتفاع مربع النص الغنية .. لقد قمت بتعديله للاستخدام العام ..

قم بإنشاء الهياكل التالية في التطبيق الخاص بك ....

[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 اعتمادًا على متطلباتك ...

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top