2010-03-02 18 views
8

¿Puede alguien explicar cómo voy a medir la cadena dentro de un control richtextbox para que pueda cambiar automáticamente el tamaño del control richtextbox de acuerdo con su contenido?Medir cadena dentro de RichTextBox Control

Gracias

Editar:

he pensado en ello, y dado que la respuesta a continuación no va a funcionar si hay diferentes tipos de letra en el control RichTextBox, qué si, pudiera conseguir la parte superior -file coords del control richtextbox y luego obtener los coords de la última línea de texto dentro de la rtb. Eso esencialmente me daría el ancho y la altura de la cadena dentro del control RichTextBox. es posible? ¿O es una mala idea hacerlo de esta manera?

Respuesta

0

Puede medir una cadena llamando al TextRenderer.MeasureText.

Sin embargo, si el texto contiene varias fuentes, esto no funcionará.

EDIT: Está buscando el método GetPositionFromCharIndex.
Tenga en cuenta que si hay varias líneas, debe tomar el máximo de las coordenadas X del último carácter en cada línea.

+0

Gracias. No entiendo muy bien esa página. ¿Por qué dibuja texto? ¿Puede enviarme un valor de ancho y alto para que pueda restablecer el tamaño de RichTextBox al nuevo tamaño? –

+0

Tal vez si hago una pregunta diferente, simplifique las cosas ... –

+0

'TextRenderer.MeasureText' no dibuja nada; simplemente devuelve el tamaño del texto en píxeles. – SLaks

2

Suponiendo que alguien está escribiendo en el control, puede usar un evento para disparar cada vez que se ingresa un carácter (incrementar el contador) y disminuir cuando se elimina. Esto te daría un conteo verdadero.

Editar:

¿Has probado esto para ajustar la altura?

richTextBox1.Height = (int)(1.5 * richTextBox1.Font.Height) + richTextBox1.GetLineFromCharIndex(richTextBox1.Text.Length + 1) * richTextBox1.Font.Height + 1 + richTextBox1.Margin.Vertical; 

richTextBox1.SelectionStart = 0; 

richTextBox1.SelectionStart = richTextBox1.Text.Length; 

O bien, puede hacerlo utilizando Anchura:

Graphics g = Graphics.FromHwnd(richTextBox1.Handle); 

SizeF f = g.MeasureString(richTextBox1.Text, richTextBox1.Font); 
richTextBox1.Width = (int)(f.Width)+5; 
+0

Esto es lo que estoy haciendo actualmente, aunque no puede tener en cuenta los estilos/tamaños de fuente de esta manera, y eventualmente la rtb no podrá mantenerse y el texto se desbordará –

+0

ver edición para ajuste de altura –

+0

Sin ofender, pero esto produce resultados muy feos. Tiene que haber una manera de hacer esto sin tener que ver como RichTextBox está a punto de explotar a través de mi monitor. –

3

Intente llamar GetPreferredSize(Size.Empty). Se define en la clase Control, y si RichTextBoxControl modifica la propiedad, debería darle lo que está buscando.

Si pasa algo que no sea Size.Empty en el método, entonces usará ese valor como una restricción máxima. Usar Size.Empty significa que el tamaño potencial no tiene límites.

+0

incluso puedes llamarlo con el ancho 'GetPreferredSize (nuevo Tamaño (ancho, 0))' y puedes obtener la altura del tamaño de la devolución llame al –

6

poner el código siguiente en el evento ContentsResized:

Private Sub rtb_ContentsResized(ByVal sender As Object, ByVal e As System.Windows.Forms.ContentsResizedEventArgs) Handles txtQuestion.ContentsResized 
     Dim h = e.NewRectangle.Height, w = e.NewRectangle.Width 
     h = Math.Max(h, sender.Font.Height) 
     h = Math.Min(h, Me.ClientSize.Height - 10 - sender.Top) 
     h += sender.Height - sender.ClientSize.Height + 1 
     sender.Height = h 
End Sub 
+0

'ContentsResized' y' e.NewRectangle' me lo arreglaron. Los otros sospechosos habituales, p. 'AutoSize',' GetPreferredSize' no parece funcionar correctamente para 'RichTextBox'. –

0

he encontrado una solución para los problemas de altura de la caja de texto enriquecido .. lo he modificado un para uso general ..

Crear siguiente estructura en su aplicación ....

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

Crear siguientes variables privadas en su clase para la forma (donde cada vez que necesita para calcular la altura de texto enriquecido)

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

Agregar método siguiente para su clase de forma

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

Es posible que deba modificar el método anterior para que funcione de acuerdo con sus requisitos ... Hacer sur e para enviar cadena RTF como parámetro al método de texto no es normal y también asegurarse de asignar ancho y la altura disponible para la variable RichTextbox en el método ...

Se puede jugar con WordWrap función de sus necesidades ...

0

Agregue a la gran respuesta de bathineni:

Antecedentes: Necesitaba medir la altura de salida RTF para renderizar en papel y porque tengo encabezados/pies de página dinámicos personalizados que necesitaba para controlar la paginación).

(RichTextBox.GetLineFromCharIndex me decepcionó debido a RTF complejo, incluidas las líneas & tablas de varias columnas con ajuste de palabras).

De todos modos todo trabajaba muy bien, hasta que alguien utiliza mi aplicación con las ventanas temida "que el texto y otros artículos más grandes o más pequeños" (configuración de DPI.) - en el momento de medición de tamaño de letra cortos más grandes que la pata de la longitud de la página cálculos (la impresora todavía procesaba el texto y las columnas correctamente; solo las longitudes de página ahora eran incorrectas).

La diferencia de factoring solo en PPP falló, ya que el texto corto grande no encajaba correctamente en los valores RTF tx y cellx de origen.

De todos modos, en caso de que otros están haciendo cosas locas similares poco de ensayo y error ocurrió lo siguiente (con el tiempo muy pocos) modificaciones al método CalculateRichTextHeight bathineni:

RichTextBox richTextBox = new RichTextBox();  // same as original 
int dpix = richTextBox.CreateGraphics().DpiX; // get dpi 
richTextBox.WordWrap = true;      // I needed this, you many not 
    // ... set size etc - same as original answer 
richTextBox.Scale(new System.Drawing.SizeF(dpix/96, dpix/96)); // scale RTB 
    // ... 
    // 96? my original calculations based on windows default 96dpi settings. 

parece que el control de otro modo oscuro. La escala (sizef) es realmente útil para algo después de todo.

Nota: si convierte los resultados a líneas impresas reales, (en mi caso, todos mis \ pard fueron "\ sl-240 \ slmult0" que sale a 16 (pix?) Por línea) también recuerde volver a factor el divisor es decir en mi caso:

lines = height/(int)(16 * (dpix/96)) 
Cuestiones relacionadas