¿Cómo puedo justificar texto en un RichTextBox?

Fco. Cortes 20 Puntos de reputación
2024-04-18T05:14:32.3+00:00

Aquí mi código, lo llamo desde un método:

private void MiMetodo( )

{

RichTextBox richTextBox = new RichTextBox(); // Crear una instancia de RichTextBox

Font font = new Font( "Microsoft Sans Serif", 12 );

int controlWidth = richTextBox.ClientSize.Width; // Ancho del RichTextBox (considerando el espacio del borde)

string textoJustificado = JustifyParagraph( RichTextBox1.Text, font, controlWidth );

RichTextBox1.Text = textoJustificado.ToString();
```}

private string JustifyParagraph(string text, Font font, int controlWidth)

{

```csharp
string[ ] lines = text.Split( new[ ] { Environment.NewLine }, StringSplitOptions.None );

StringBuilder result = new StringBuilder();

foreach ( string line in lines )

{

    string justifiedLine = Justify( line, font, controlWidth );

    result.AppendLine( justifiedLine );

}

return result.ToString().TrimEnd();
```}

private string Justify(string line, Font font, int controlWidth)

{

```csharp
string[ ] words = line.Split( ' ' );

StringBuilder justifiedLine = new StringBuilder();

int totalSpaces = controlWidth - TextRenderer.MeasureText( line, font ).Width;

int numWords = words.Length;

if ( numWords == 1 )

{

    // Si solo hay una palabra, no es necesario justificarla

    return line;

}

int spacesPerWord = totalSpaces / ( numWords - 1 );

int extraSpaces = totalSpaces % ( numWords - 1 );

for ( int i = 0; i < numWords; i++ )

{

    justifiedLine.Append( words[ i ] );

    if ( i < numWords - 1 )

    {

        int spacesToAdd = spacesPerWord + ( i < extraSpaces ? 1 : 0 );

        if ( spacesToAdd > 0 ) // Evita agregar espacios negativos

        {

            justifiedLine.Append( ' ', spacesToAdd );

        }

    }

}

return justifiedLine.ToString();
```}
Preguntas y respuestas (Q&A) de Microsoft
Preguntas y respuestas (Q&A) de Microsoft
Use esta etiqueta para compartir sugerencias, solicitudes de características y errores con el equipo de Microsoft Q&A. El equipo de Microsoft Q&A evaluará sus comentarios periódicamente y proporcionará actualizaciones a lo largo del proceso.
182 preguntas
0 comentarios No hay comentarios
{count} votos

Respuesta aceptada
  1. Enrykez 75 Puntos de reputación
    2024-04-18T17:11:28.42+00:00

    Para lograr el justificado de una manera eficiente vas a necesitar crear un mini proyecto adjunto a tu solución en código Visual Basic (no importa que tu proyecto donde lo usaras este en C#).

    1. Agrega a tu solución un nuevo proyecto Visual Basic -WindowsForm (no importa el nombre) en Visual Basic (tampoco importa si tu proyecto original lo estas trabajando en C# o en VB.NET) al compilarse son compatibles ambos códigos. User's image
    2. Agrega a dicho proyecto una clase llamada SmartBox.vb. User's image
      1. Dentro de la clase, copia el siguiente código tal cual:
         Imports System.Windows.Forms
         Imports System.Runtime.InteropServices
         ' Represents a standard RichTextBox with some minor added functionality.
         ' SmartBox provides methods to maintain performance while it is being updated.
         ' Additional formatting features have also been added.
         Public Class SmartBox
             Inherits RichTextBox
             ' Maintains performance while updating.
             ' Remember to call EndUpdate when you are finished with the update.
             ' Nested calls are supported.
             ' Calling this method will prevent redrawing.
             ' It will also setup the event mask of the underlying richedit
             ' control so that no events are sent.
             Public Sub BeginUpdate()
                 ' Deal with nested calls.
                 updating += 1
                 If updating > 1 Then
                     Return
                 End If
                 ' Prevent the control from raising any events.
                 oldEventMask = SendMessage(New HandleRef(Me, Handle), EM_SETEVENTMASK, 0, 0)
                 ' Prevent the control from redrawing itself.
                 SendMessage(New HandleRef(Me, Handle), WM_SETREDRAW, 0, 0)
             End Sub
             Public Sub EndUpdate()
                 ' Resumes drawing and event handling.
                 ' This method should be called every time a call is made
                 ' made to BeginUpdate. It resets the event mask to it's
                 ' original value and enables redrawing of the control.
                 updating -= 1     ' Deal with nested calls.
                 If updating > 0 Then
                     Return
                 End If
                 SendMessage(New HandleRef(Me, Handle), WM_SETREDRAW, 1, 0) ' Allow the control to redraw itself.
                 SendMessage(New HandleRef(Me, Handle), EM_SETEVENTMASK, 0, oldEventMask)
                 ' Allow the control to raise event messages.
             End Sub
             Public Shadows Property SelectionAlignment() As TextAlign
                 ' Gets or sets the alignment to apply to the current selection or insertion point.
                 ' Replaces the SelectionAlignment from RichTextBox
                 Get
                     Dim fmt As New PARAFORMAT()
                     fmt.cbSize = Marshal.SizeOf(fmt)
                     ' Get the alignment.
                     SendMessage(New HandleRef(Me, Handle), EM_GETPARAFORMAT, SCF_SELECTION, fmt)
                     ' Default to Left align.
                     If (fmt.dwMask And PFM_ALIGNMENT) = 0 Then
                         Return TextAlign.Left
                     End If
                     Return CType(fmt.wAlignment, TextAlign)
                 End Get
                 Set(value As TextAlign)
                     Dim fmt As New PARAFORMAT()
                     fmt.cbSize = Marshal.SizeOf(fmt)
                     fmt.dwMask = PFM_ALIGNMENT
                     fmt.wAlignment = CShort(value)
                     ' Set the alignment.
                     SendMessage(New HandleRef(Me, Handle), EM_SETPARAFORMAT, SCF_SELECTION, fmt)
                 End Set
             End Property
             Protected Overrides Sub OnHandleCreated(e As EventArgs)
                 ' This member overrides OnHandleCreated.
                 MyBase.OnHandleCreated(e)
                 ' Enable support for justification.
                 SendMessage(New HandleRef(Me, Handle), EM_SETTYPOGRAPHYOPTIONS, TO_ADVANCEDTYPOGRAPHY, TO_ADVANCEDTYPOGRAPHY)
             End Sub
             Private updating As Integer = 0
             Private oldEventMask As Integer = 0
             ' Constants from the Platform SDK.
            Private Const EM_SETEVENTMASK As Integer = 1073         '1073
             Private Const EM_GETPARAFORMAT As Integer = 1085        '1085
             Private Const EM_SETPARAFORMAT As Integer = 1095        '1095
             Private Const EM_SETTYPOGRAPHYOPTIONS As Integer = 1226 '1226
             Private Const WM_SETREDRAW As Integer = 11              '11
             Private Const TO_ADVANCEDTYPOGRAPHY As Integer = 1      '1
            Private Const PFM_ALIGNMENT As Integer = 8              '8
             Private Const SCF_SELECTION As Integer = 1              '1
             ' It makes no difference if we use PARAFORMAT or
             ' PARAFORMAT2 here, so I have opted for PARAFORMAT2.
             <StructLayout(LayoutKind.Sequential)>
             Private Structure PARAFORMAT
                 Public cbSize As Integer
                 Public dwMask As UInteger
                 Public wNumbering As Short
                 Public wReserved As Short
                 Public dxStartIndent As Integer
                 Public dxRightIndent As Integer
                 Public dxOffset As Integer
                 Public wAlignment As Short
                 Public cTabCount As Short
                 <MarshalAs(UnmanagedType.ByValArray, SizeConst:=32)>
                 Public rgxTabs As Integer()
                 ' PARAFORMAT2 from here onwards.
                 Public dySpaceBefore As Integer
                 Public dySpaceAfter As Integer
                 Public dyLineSpacing As Integer
                 Public sStyle As Short
                 Public bLineSpacingRule As Byte
                 Public bOutlineLevel As Byte
                 Public wShadingWeight As Short
                 Public wShadingStyle As Short
                 Public wNumberingStart As Short
                 Public wNumberingStyle As Short
                 Public wNumberingTab As Short
                 Public wBorderSpace As Short
                 Public wBorderWidth As Short
                 Public wBorders As Short
             End Structure
             <DllImport("user32", CharSet:=CharSet.Auto)>
             Private Shared Function SendMessage(hWnd As HandleRef, msg As Integer, wParam As Integer, lParam As Integer) As Integer
             End Function
             <DllImport("user32", CharSet:=CharSet.Auto)>
             Private Shared Function SendMessage(hWnd As HandleRef, msg As Integer, wParam As Integer, ByRef lp As PARAFORMAT) As Integer
             End Function
         End Class
         Public Enum TextAlign
             ' Specifies how text in a SmartBox is horizontally aligned.
             Left = 1 ' The text is aligned to the left.
             Right = 2 ' The text is aligned to the right.
             Center = 3 ' The text is aligned in the center.
             Justify = 4 ' The text is justified.
         End Enum
         
      
    3. Sobre el proyecto de VisualBasic da click derecho y selecciona la opción establecer como proyecto de inicio. User's image
      1. Ahora ve al código del formulario y escribe solo lo siguiente (ninguna otra cosa mas):
         Public Class Form1
             Public SmartBox As SmartBox = New SmartBox
             Private Sub Form1_Load()
             End Sub
         End Class
         
      
    4. Ejecuta el proyecto UNA SOLA VEZ.
    5. Ahora finaliza el proyecto.
    6. Revisa en el Toolbox que ahora existe un componenete llamado SmartBox:
    7. Establece tu proyecto de C# como proyecto de inicio.
    8. Ahora puedes arrastrar el componente SmartBox sobre tu formulario y utilizarlo para justificar utilizando la propiedad smartBox1.SelectionAlignment = WinFormsApp2.TextAlign.Justify;
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private void button1_Click(object sender, EventArgs e)
        {
            smartBox1.SelectionAlignment = WinFormsApp2.TextAlign.Justify;
        }
    }
    
    1. User's image User's image
    2. Clic en el botón Justificar: User's image
    3. Listo, RichTextBox con Justificación. Basado en lo descrito por: vbforoums
    0 comentarios No hay comentarios

0 respuestas adicionales

Ordenar por: Muy útil