none
¿Me ayudan a que este control de usuario tenga una propiedad TextAlign? (pequeño código, explico)

    Pregunta

  • Con este pequeño código visualizo etiquetas transparentes (hereda las características del control Label) y funciona pero no tiene una propiedad TextAlign y por tanto el texto siempre se justifica a la izquierda.

    Me parece que añadiendo algunas líneas se puede lograr que aparezca la propiedad TextAlign (y si se pudiera también la propiedad autosize).

    El código es el siguiente:

    ------------------------------------------------------------

    Public Class EtiquetaTransparente
      Inherits Control

      Protected Overrides ReadOnly Property CreateParams() As System.Windows.Forms.CreateParams
        Get
          Dim oParametros As CreateParams = MyBase.CreateParams
          oParametros.ExStyle = oParametros.ExStyle Or &H20
          Return oParametros
        End Get
      End Property

      Protected Overrides Sub OnPaintBackground(ByVal e As System.Windows.Forms.PaintEventArgs)
      End Sub

      '*** Crea una brocha del color de la fuente original y dibuja sólo el texto
      Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
        e.Graphics.DrawString(Text, Font, New SolidBrush(ForeColor), -1, 0)
      End Sub

    End Class

    ------------------------------------------------------------



    • Editado James-2016 lunes, 19 de diciembre de 2016 0:17
    domingo, 18 de diciembre de 2016 23:58

Respuestas

  • Para añadir el TextAlign, primero necesitas poner en la clase una propiedad pública llamada TextAlign, que guarde el valor asignado desde fuera. Y luego, dentro del OnPaint tienes que leer el contenido de esa propiedad y hacer el DrawString de distintas maneras dependiendo del TextAlign. El truco está en usar el método e.Graphics.MeasureString para calcular cuánto mide la cadena. Con ese dato, si quieres alinear el texto a la derecha, restas de la anchura del control la longitud de la cadena, y eso te da la coordenada X que le tienes que pasar al Drawstring. Y si quieres mostrar el texto centrado, tomas la longitud devuelta por el MeasureString, la restas de la anchura del control, divides por 2, y esa es la X para el DrawString.

    Para usar el AutoSize, calculas la longitud con MeasureString, y ese valor se lo pones al Me.Width del control.

    • Marcado como respuesta James-2016 lunes, 19 de diciembre de 2016 11:28
    lunes, 19 de diciembre de 2016 9:20
  • El CreateParams te devuelve unos parámetros heredados de la clase Control. Entre ellos hay algunos que no se deben tocar, como la anchura y la altura, dado que ya se exponen a través de propiedades específicas para ello. pero hay otros que representan información que no está accesible de otra manera, pos ejemplo, los estilos que internamente se pasan a la API de Windows, como el ExStyle de tu ejemplo. No sé concretamente qué se cambia con el &H20, habría que mirar la documentación técnica de las APIs correspondientes a ver qué hace.

    El AutoSize ya existe en la clase Control, por eso el compilador avisa de que al definir AutoSize en tu clase heredada estás "pisando" el AutoSize que heredaste de la clase madre. Si realmente quieres suplantar el AutoSize original, puedes usar la palabra Override en la declaración: "Public Override Property ...". Si no quieres sustituir la funcionalidad del AutoSize de la clase Control, entonces lo mejor es que le cambies el nombre y dejes las dos propiedades accesibles.

    • Marcado como respuesta James-2016 lunes, 19 de diciembre de 2016 15:39
    lunes, 19 de diciembre de 2016 15:09

Todas las respuestas

  • Para añadir el TextAlign, primero necesitas poner en la clase una propiedad pública llamada TextAlign, que guarde el valor asignado desde fuera. Y luego, dentro del OnPaint tienes que leer el contenido de esa propiedad y hacer el DrawString de distintas maneras dependiendo del TextAlign. El truco está en usar el método e.Graphics.MeasureString para calcular cuánto mide la cadena. Con ese dato, si quieres alinear el texto a la derecha, restas de la anchura del control la longitud de la cadena, y eso te da la coordenada X que le tienes que pasar al Drawstring. Y si quieres mostrar el texto centrado, tomas la longitud devuelta por el MeasureString, la restas de la anchura del control, divides por 2, y esa es la X para el DrawString.

    Para usar el AutoSize, calculas la longitud con MeasureString, y ese valor se lo pones al Me.Width del control.

    • Marcado como respuesta James-2016 lunes, 19 de diciembre de 2016 11:28
    lunes, 19 de diciembre de 2016 9:20
  • mm  con un poco de código usando el MeasureString se logra simular esas propiedades. Gracias, lo anterior resuelve lo que trato de hacer.

    El código anterior lo adapte de otros que encontré por la red pero no lo entiendo bien,  qué hace CreateParams() exactamente?

    ------------------------------------

    Una última cosita:

    Ya le pude añadir funcionalidad a la propiedad TextAlign, al intentar hacer lo propio con AutoSize me dice que "Autosize prevalece sobre un método..." podría utilizar otro nombre, pero me gustaría que se siga llamando igual.

    ¿cómo lo invalidaría como dice la imagen que adjunto para poder utilizar ese mismo nombre en una propiedad?



    • Editado James-2016 lunes, 19 de diciembre de 2016 13:37
    lunes, 19 de diciembre de 2016 11:28
  • El CreateParams te devuelve unos parámetros heredados de la clase Control. Entre ellos hay algunos que no se deben tocar, como la anchura y la altura, dado que ya se exponen a través de propiedades específicas para ello. pero hay otros que representan información que no está accesible de otra manera, pos ejemplo, los estilos que internamente se pasan a la API de Windows, como el ExStyle de tu ejemplo. No sé concretamente qué se cambia con el &H20, habría que mirar la documentación técnica de las APIs correspondientes a ver qué hace.

    El AutoSize ya existe en la clase Control, por eso el compilador avisa de que al definir AutoSize en tu clase heredada estás "pisando" el AutoSize que heredaste de la clase madre. Si realmente quieres suplantar el AutoSize original, puedes usar la palabra Override en la declaración: "Public Override Property ...". Si no quieres sustituir la funcionalidad del AutoSize de la clase Control, entonces lo mejor es que le cambies el nombre y dejes las dos propiedades accesibles.

    • Marcado como respuesta James-2016 lunes, 19 de diciembre de 2016 15:39
    lunes, 19 de diciembre de 2016 15:09
  • aaah, para suplantar AutoSize simplemente había que añadir Overrides a la declaración de la propiedad, pero creo que, como dice, es mejor usar otro nombre para tener ambas disponibles.

    Gracias por la explicación, gracias por todo.

    lunes, 19 de diciembre de 2016 15:39