2009-04-09 7 views

Antwort

2

Es ist ein bisschen Schmerz - die C# RichTextBox ist oft frustrierend mit zu arbeiten. Versuchen Sie, die Box groß genug zu dimensionieren, um den Inhalt ohne Scrollbalken zu halten?

Wenn die RichTextBox eine konstante Schriftart hat, können Sie TextRenderer.MeasureText verwenden, um einfach die erforderliche Größe zu messen und die Breite der Box als Einschränkung zu übergeben.

Das ContentsResized-Ereignis gibt Ihnen ein ContentsResizedEventsArgs, das Ihnen ein NewRectangle gibt, das Ihnen mitteilt, wie groß der Textbereich ist. Aber es wird nur ausgelöst, wenn sich der Text ändert, was nicht so nützlich ist, wenn Sie einfach eine existierende Richtextbox messen möchten (obwohl Sie wahrscheinlich etwas Hackiges tun könnten, wie den Text der Box auf sich selbst setzen und dieses Ereignis auslösen).

Es gibt auch eine Reihe von Win32-API-Aufrufe, wie mit EM_GETLINECOUNT (http://ryanfarley.com/blog/archive/2004/04/07/511.aspx) usw.

+0

ContentsResized Ereignis als Hack wirklich funktioniert, dank – Nigrimmist

0

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

in Ihrer Anwendung erstellen folgende structs ....

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

für Formular erstellen folgende private Variablen in Ihrer Klasse (wo immer Sie Rich-Text berechnen müssen Höhe)

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

in Ihre Klasse für Form

folgende Methode
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 möglicherweise über Verfahren ändern, um es wie pro Ihre Anforderung funktioniert ... Stellen Sie sicher, Rtf senden string als Parameter für Methode nicht normalen Text und stellen Sie sicher, dass die Variable Richtextbox in der Methode ...

die verfügbare Breite und Höhe zuweisen Sie können mit WordWrap je nach Ihren Anforderungen spielen ..

1

Eine wirklich billige Lösung (eine, die potentiell mit Problemen behaftet ist) besteht darin, ein Autofit-Etikett gleichzeitig mit Text in der gleichen Schriftart und Größe zu füllen und dann die Breite des Etiketts auf die Breite des RTBs zu kopieren.

So, wie folgt aus:

RichTextBox rtb = new RichTextBox(); 
rtb.Text = "this is some text"; 
rtb.Font = new Font("Franklin Gothic Medium Cond", 10, FontStyle.Regular); 

Label fittingLabel = new Label(); 
fittingLabel.Text = rtb.Text; 
fittingLabel.Font = rtb.Font; 
fittingLabel.AutoSize = true; 

//Not sure if it's necessary to add the label to the form for it to autosize... 
fittingLabel.Location = new Point(-1000,-1000); 
this.Controls.Add(fittingLabel); 

rtb.Width = fittingLabel.Width; 

this.Controls.Remove(fittingLabel); 
+0

Es ist sicherlich eine bessere Lösung dann diese. Das ist so ein schmutziger Hack – thecoshman

+0

Ha Ha. Es funktioniert ... –

6

Wieder eine feste Schriftart unter der Annahme, könnten Sie so etwas wie:

using (Graphics g = CreateGraphics()) 
{ 
    richTextBox.Height = (int)g.MeasureString(richTextBox.Text, 
     richTextBox.Font, richTextBox.Width).Height; 
} 
+1

Damit der Text richtig passt, benötigen Sie eine +10. Zumindest hat das für mich funktioniert. –

5

Ich glaube, ich bin viel zu spät, aber einen Blick auf this

nehmen

Es sind nur zwei Codezeilen:

private void rtb_ContentsResized(object sender, ContentsResizedEventArgs e) 
{ 
    (RichTextBox)sender.Height = e.NewRectangle.Height + 5; 
} 
+0

Das hat genau das gemacht, was ich brauchte. Beachten Sie, dass 'wordwrap' muss =' true' – gunfulker

0

Es ist viel einfacher zu verwenden GetPreferredSize, wie in dieser Antwort beschrieben. Dann müssen Sie nicht auf ein ContentsResized-Ereignis warten.

1

sehen diese link

Sie gerade dieses ContentsResized Ereignis gleiche verwenden:

private void rtb_ContentsResized(object sender, ContentsResizedEventArgs e) 
{ 
     ((RichTextBox)sender).Height = e.NewRectangle.Height + 5; 
}