elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Estamos en la red social de Mastodon


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación General
| | |-+  .NET (C#, VB.NET, ASP) (Moderador: kub0x)
| | | |-+  ListView con salto de línea /multilinea
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] 2 Ir Abajo Respuesta Imprimir
Autor Tema: ListView con salto de línea /multilinea  (Leído 11,037 veces)
okik


Desconectado Desconectado

Mensajes: 462


Ver Perfil
ListView con salto de línea /multilinea
« en: 11 Diciembre 2016, 14:37 pm »

hola, me gustaría saber si se puede introducir ítems en un Listbox de modo que se vean verticales

del modo normal sería

12345678
45664555
78999999

Pero yo quiero hacerlo así

1 4 7
2 5 8
3 6 9
4 6 9
5 4 9
6 5 9
7 5 9
8 5 9



Si hago esto por ejemplo...
Código
  1.  
  2.        Dim Num() As String = {"1", "2", "3", "4"}
  3.        Dim strLinea As String = Nothing
  4.        strLinea = String.Join(Environment.NewLine, Num).Trim
  5.        ListBox1.Items.Add(strLinea)
  6.        Label1.Text= strLinea
  7.  

 el Label1 muestra correctamente:
Código:
1
2
3
4

Mientras que un Listbox o un ListView lo mostraría así
Código:
1234

El ListBox aunque lo mostrara como el label pondría uno debajo del otro. Con un Listview podría ponerlo en cada columna, pero también lo pone horizontal.

Lo he hecho con un FlowLayoutPanel1 Panel,  y añado Labels de forma automática pero no es lo que busco. Además que me ocupa mucho código y es tedioso de hacer.

¿Alguna idea?

Gracias



Acebo de darme cuenta que además con Panel, no puedo hacer multiselección


« Última modificación: 11 Diciembre 2016, 16:15 pm por okik » En línea

Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.788



Ver Perfil
Re: ListView con salto de línea /multilinea
« Respuesta #1 en: 11 Diciembre 2016, 18:51 pm »

Hola.

El problema con un ListBox y un ListView es que automaticamente acomodan los caracteres de salto de linea para la vista en horizontal, para representarlo como una sola linea. Me parece que la única solución sería heredar la class ListBox o ListView con OwnerDraw para dibujar manualmente los rectángulos de los items y el contenido de texto, se puede hacer (al menos con un ListView), pero es una solución tediosa que requeriría tiempo y esfuerzo.



Con un ListBox, para hacerlo vertical puedes pasarle un array, esto significa que si tenemos el string "12345678", cada caracter "{1, 2, 3, 4, 5, 6, 7, 8}" será seleccionado por individual, no se si eso te parecerá bien.



Código
  1. With ListBox1
  2.    .MultiColumn = True
  3.    .IntegralHeight = False
  4.    .Font = New Font(.Font.FontFamily, 14.0F)
  5.    .ColumnWidth = CInt(Math.Ceiling(.Font.Size))
  6.    .Size = New Size((.ColumnWidth * 4), 200)
  7. End With
  8.  
  9. Dim arr1 As String() = {"1", "2", "3", "4", "5", "6", "7", "8"}
  10. Dim arr2 As String() = {"4", "5", "6", "6", "4", "5", "5", "5"}
  11. Dim arr3 As String() = {"7", "8", "9", "9", "9", "9", "9", "9"}
  12.  
  13. ListBox1.Items.AddRange(arr1)
  14. ListBox1.Items.AddRange(arr2)
  15. ListBox1.Items.AddRange(arr3)



Con un ListView, puedes utilizar el modo de vista LargeIcon, sin embargo, para que se muestre en vertical debemos activar la propiedad LabelWrap, y esto nos da un resultado visual poco agradable sobre los items que no están seleccionados, puesto que no podemos redimensionar el tamaño de los rectángulos de cada item a menos que heredemos el control:



Código
  1. With ListView1
  2.    .Font = New Font(.Font.FontFamily, 12.25F)
  3.    .View = View.LargeIcon
  4.    .LabelWrap = True
  5. End With
  6.  
  7. Dim str1 As String = String.Join(ControlChars.Lf, {"1", "2", "3", "4", "5", "6", "7", "8"})
  8. Dim str2 As String = String.Join(ControlChars.Lf, {"4", "5", "6", "6", "4", "5", "5", "5"})
  9. Dim str3 As String = String.Join(ControlChars.Lf, {"7", "8", "9", "9", "9", "9", "9", "9"})
  10.  
  11. Dim item1 As New ListViewItem(str1)
  12. Dim item2 As New ListViewItem(str2)
  13. Dim item3 As New ListViewItem(str3)
  14.  
  15. ListView1.Items.AddRange({item1, item2, item3})



Con un DataGridView ocurre exactamente lo mismo por defecto, los caracteres de salto linea se acomodan para la vista en horizontal (las lineas en blanco no se eliminan del item, tampoco en un Listview, simplemente el control representa el texto en las filas sin las lineas en blanco), sin embargo, el DataGridView es un control mucho más personalizable que un ListView, así que podemos adaptarlo a nuestras necesidades de vista de filas en vertical y el resultado quedará bastante bien:



Código
  1. With DataGridView1
  2.    .Columns.Add("Column1", "")
  3.    .Columns.Add("Column2", "")
  4.    .Columns.Add("Column3", "")
  5.  
  6.    .Font = New Font(.Font.FontFamily, 12.25F)
  7.    .AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells
  8.    .DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter
  9.    .DefaultCellStyle.WrapMode = DataGridViewTriState.True
  10. End With
  11.  
  12. Dim str1 As String = String.Join(ControlChars.Lf, {"1", "2", "3", "4", "5", "6", "7", "8"})
  13. Dim str2 As String = String.Join(ControlChars.Lf, {"4", "5", "6", "6", "4", "5", "5", "5"})
  14. Dim str3 As String = String.Join(ControlChars.Lf, {"7", "8", "9", "9", "9", "9", "9", "9"})
  15.  
  16. DataGridView1.Rows.Add({str1, str2, str3})

En resumen, tu mejor opción es recurrir al control DataGridView, o bien heredar la class ListView, activar el OwnerDraw para dibujar manualmente el contenido del control y trastear con el StringFormat, StringAlignment, y los Bounds para intentar conseguir el resultado de vista en vertical (que no estoy muy seguro de si se podrá, depende de los miembros que sean accesibles]).

Saludos!


« Última modificación: 11 Diciembre 2016, 19:56 pm por Eleкtro » En línea

okik


Desconectado Desconectado

Mensajes: 462


Ver Perfil
ListView con salto de línea /multilinea
« Respuesta #2 en: 12 Diciembre 2016, 01:13 am »

Gracias @Elektro

Hay que ver como te curras las respuestas, me sabe mal y todo.

el DataGridView parece una buena opción, lo probaré a ver. No se me había ocurrido probar con él.

La verdad es que no entiendo como no se puede. Como aquí en la primera columna:




Lo intenté con API, con SendMessage, y probando conseguí cosas interesantes pero no eso.

En línea

Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.788



Ver Perfil
Re: ListView con salto de línea /multilinea
« Respuesta #3 en: 12 Diciembre 2016, 03:19 am »

La verdad es que no entiendo como no se puede. Como aquí en la primera columna:




Lo intenté con API, con SendMessage, y probando conseguí cosas interesantes pero no eso.

Poder se puede, como ya dije, pero es que lo que muestras en esa imagen, no es un ListView por defecto, en todo cado puede ser un DataGridView modificado, o un ListView que ha sido modificado, es decir, un user-control personalizado. Puedes hacer lo mismo que en esa imagen, como ya dije, heredando la class ListView.

Aquí tienes un ejemplo base:

No necesitas en ningún momento recurrir a las funciones de la API de Windows, eso déjalo para circunstancias en donde no puedas controlarlo de otra forma más directa; al heredar la class ListView, obtienes todo el control necesario, haciendo uso de los miembros heredados, para personalizar la manera en que se renderiza el control (añadir barras de progreso, hacer el texto multi-linea, cambiar los colores por defecto, etc), simplemente aprende a hacerlo:


Pero ya te digo, lo veo una pérdida de tiempo, cuando puedes usar un DataGridView y darle una apariencia similar a un ListView (suponiendo que eso sea lo que te frena).

Saludos!
« Última modificación: 12 Diciembre 2016, 03:24 am por Eleкtro » En línea

ivancea96


Desconectado Desconectado

Mensajes: 3.412


ASMático


Ver Perfil WWW
Re: ListView con salto de línea /multilinea
« Respuesta #4 en: 12 Diciembre 2016, 19:49 pm »

Esos saltos de línea que ves en la primera columna los genera automáticamente el DataGridView cuando le colocas a la columna DefaultCellStyle->WrapMode = true
Solo existen en la visualización; si agrandases la columna, se recolocaría.
En línea

okik


Desconectado Desconectado

Mensajes: 462


Ver Perfil
Re: ListView con salto de línea /multilinea
« Respuesta #5 en: 12 Diciembre 2016, 22:45 pm »

Gracias

El DataGridView va perfecto. No se me ocurrió utilizarlo porque lo usaba para base de datos, modificar tablas .

Código
  1. Public Class Form1
  2.    Dim DataGridView1 As New DataGridView
  3.    Sub New()
  4.        ' Llamada necesaria para el diseñador.
  5.        InitializeComponent()
  6.        ' Agregue cualquier inicialización después de la llamada a InitializeComponent().
  7.        Me.Controls.Add(Me.DataGridView1)
  8.    End Sub
  9.    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
  10.        With DataGridView1
  11.            .DefaultCellStyle.WrapMode = DataGridViewTriState.True
  12.            .RowHeadersVisible = False
  13.            .ColumnHeadersVisible = False
  14.            .ReadOnly = True
  15.            .RowCount = 1
  16.            .AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.DisplayedCells
  17.            ' .AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.DisplayedCells
  18.            .MultiSelect = True
  19.            .ClipboardCopyMode = DataGridViewClipboardCopyMode.EnableWithoutHeaderText 'Permite copiar el texto
  20.            .RowsDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter 'coloca los valores en el centro
  21.            .Size = New Size(New Point(400, 235))
  22.        End With
  23.        'Configuración de las cabeceras de las columna
  24.        With DataGridView1.ColumnHeadersDefaultCellStyle
  25.            .Font = New Font("Lucida Console Unicode", FontStyle.Bold)
  26.            .Alignment = DataGridViewContentAlignment.MiddleCenter 'coloca el texto en el centro
  27.        End With
  28.  
  29.        Dim nvars As Integer = 20
  30.        DataGridView1.ColumnCount = nvars
  31.        Task.Factory.StartNew(Sub()
  32.                                  For I As Integer = 0 To nvars - 1
  33.                                      Dim Integ As Integer = I
  34.                                      Me.Invoke(DirectCast(Sub()
  35.  
  36.                                                               DataGridView1.Columns(Integ).Width = 30
  37.                                                               DataGridView1.Item(Integ, 0).Value = Serie1()
  38.  
  39.                                                               System.Threading.Thread.Sleep(50)
  40.                                                           End Sub, MethodInvoker))
  41.  
  42.                                  Next
  43.                              End Sub)
  44.  
  45.    End Sub
  46.    Public Function Serie1() As String
  47.        Dim col(16) As String
  48.        Dim Rand As New Random
  49.        For index As Integer = 1 To col.Count - 1
  50.            col(index) = CStr(Rand.Next(0, 16))
  51.        Next
  52.        Return CStr(String.Join(Environment.NewLine, col).Trim)
  53.    End Function
  54. End Class
  55.  
  56.  



Lo malo es que no parece que pueda evitar que las columnas no sean redimensionables y al mismo tiempo en la creación de la columna establecer el ancho de la misma.


« Última modificación: 12 Diciembre 2016, 23:13 pm por okik » En línea

ivancea96


Desconectado Desconectado

Mensajes: 3.412


ASMático


Ver Perfil WWW
Re: ListView con salto de línea /multilinea
« Respuesta #6 en: 12 Diciembre 2016, 22:58 pm »

Sí, puedes evitar que sean redimensionables, una a una. Tienes que ir a editar columnas y ahí ves todas sus propiedades.

También tiene el DataGridView unos campos que son los "default", que afectan a todas las columnas, filas y celdas que no tengan un "valor explícito".

Todo lo puedes hacer, échale un ojo a las propiedades detenidamente.
En línea

okik


Desconectado Desconectado

Mensajes: 462


Ver Perfil
Re: ListView con salto de línea /multilinea
« Respuesta #7 en: 12 Diciembre 2016, 23:17 pm »

Sí, puedes evitar que sean redimensionables, una a una. Tienes que ir a editar columnas y ahí ves todas sus propiedades.

También tiene el DataGridView unos campos que son los "default", que afectan a todas las columnas, filas y celdas que no tengan un "valor explícito".

Todo lo puedes hacer, échale un ojo a las propiedades detenidamente.

claro que puedo evitar que sea redimensionable si ajusto establezco:
Código:
DataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.DisplayedCells

Pero entonces ya no puedo establecer el ancho, aunque lo haga lo ignora.



Vale, la solución es usar Padding junto con DisplayedCells

Código
  1.  
  2.   DataGridView1.DefaultCellStyle.Padding = New Padding(5, 2, 5, 2)
  3.            DataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.DisplayedCells
  4.  

Donde:
Padding(X(izquierdo), Y(Arriba), X(derecho), Y(abajo))

Código
  1. Public Class Form1
  2.    Dim DataGridView1 As New DataGridView
  3.    Sub New()
  4.        ' Llamada necesaria para el diseñador.
  5.        InitializeComponent()
  6.        ' Agregue cualquier inicialización después de la llamada a InitializeComponent().
  7.        Me.Controls.Add(Me.DataGridView1)
  8.    End Sub
  9.    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
  10.        With DataGridView1
  11.  
  12.            .DefaultCellStyle.WrapMode = DataGridViewTriState.True
  13.            .RowHeadersVisible = False
  14.            .ColumnHeadersVisible = False
  15.            .ReadOnly = True
  16.            .RowCount = 1
  17.            .AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.DisplayedCells
  18.            .DefaultCellStyle.Padding = New Padding(5, 2, 5, 2)
  19.            .AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.DisplayedCells
  20.            .MultiSelect = True
  21.            .ClipboardCopyMode = DataGridViewClipboardCopyMode.EnableWithoutHeaderText 'Permite copiar el texto
  22.            .RowsDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter 'coloca los valores en el centro
  23.            .Size = New Size(New Point(400, 240))
  24.        End With
  25.  
  26.        Dim nvars As Integer = 20
  27.        DataGridView1.ColumnCount = nvars
  28.        Task.Factory.StartNew(Sub()
  29.                                  For I As Integer = 0 To nvars - 1
  30.                                      Dim Integ As Integer = I
  31.                                      Me.Invoke(DirectCast(Sub()
  32.                                                               DataGridView1.Item(Integ, 0).Value = Serie1()
  33.                                                               System.Threading.Thread.Sleep(50)
  34.                                                           End Sub, MethodInvoker))
  35.  
  36.                                  Next
  37.                              End Sub)
  38.  
  39.    End Sub
  40.    Public Function Serie1() As String
  41.        Dim col(16) As String
  42.        Dim Rand As New Random
  43.        For index As Integer = 1 To col.Count - 1
  44.            col(index) = CStr(Rand.Next(0, 16).ToString("00"))
  45.        Next
  46.        Return CStr(String.Join(Environment.NewLine, col).TrimStart)
  47.    End Function
  48. End Class
  49.  




Bueno, pues GRACIAS a los dos. Lo doy por solucionado  ;-)
« Última modificación: 12 Diciembre 2016, 23:44 pm por okik » En línea

ivancea96


Desconectado Desconectado

Mensajes: 3.412


ASMático


Ver Perfil WWW
Re: ListView con salto de línea /multilinea
« Respuesta #8 en: 13 Diciembre 2016, 12:05 pm »

Para evitar usar padding y tener un ancho fijo, le colocas el Width, le colocas Resizable a False y AutoSize a None.
En línea

Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.788



Ver Perfil
Re: ListView con salto de línea /multilinea
« Respuesta #9 en: 13 Diciembre 2016, 14:47 pm »

Conviene que no interactues con el control para construir las columnas y filas, en su lugar puedes definir un DataTable y construir la tabla allí, y entonces usar la propiedad DataSource del DataGridView. Recuerda, cuanta menos interacción directa exista por parte de tu código con los controles, mejor.

He extendido mucho (realmente mucho) el siguiente ejemplo, pero bueno, así es como lo haría yo:

Primeramente, definimos un type para almacenar y/o generar secuencias numéricas aleatorias. Aparte de servirnos para la representación epxlícita de este tipo de secuencias numéricas, otra diferencia (o ventaja) entre una colección List(Of Integer()) y esto, es que podremos reutilizarlo para muchos otros propósitos en el futuro:

Código
  1. Public Class RandomSequence
  2.  
  3.    Protected Shared ReadOnly rand As New Random()
  4.  
  5.    Public ReadOnly Property Value As Integer()
  6.        Get
  7.            Return Me.valueB
  8.        End Get
  9.    End Property
  10.    Protected valueB As Integer()
  11.  
  12.    Public ReadOnly Property Value(ByVal format As String) As String
  13.        Get
  14.            Return Me.ToString(New IntegerSequenceFormatter(), format)
  15.        End Get
  16.    End Property
  17.  
  18.    Public ReadOnly Property Length As Integer
  19.        Get
  20.            Return Me.lengthB
  21.        End Get
  22.    End Property
  23.    Protected lengthB As Integer
  24.  
  25.    Private Sub New()
  26.    End Sub
  27.  
  28.    Protected Friend Sub New(ByVal value As Integer())
  29.        Me.valueB = value
  30.        Me.lengthB = value.Length
  31.    End Sub
  32.  
  33.    Protected Friend Sub New(ByVal length As Integer)
  34.        Me.valueB = Me.GenerateSequence(length).ToArray()
  35.        Me.lengthB = length
  36.    End Sub
  37.  
  38.    Protected Friend Sub New(ByVal length As Integer, ByVal minValue As Integer, ByVal maxValue As Integer)
  39.        Me.valueB = Me.GenerateSequenceInternal(length, minValue, maxValue).ToArray()
  40.        Me.lengthB = length
  41.    End Sub
  42.  
  43.    Public Overridable Function GenerateSequence(ByVal length As Integer) As Integer()
  44.        Me.valueB = Me.GenerateSequenceInternal(length, minValue:=0, maxValue:=Integer.MaxValue).ToArray()
  45.        Return Me.valueB
  46.    End Function
  47.  
  48.    Public Overridable Function GenerateSequence(ByVal length As Integer, ByVal minValue As Integer, ByVal maxValue As Integer) As Integer()
  49.        Me.valueB = Me.GenerateSequenceInternal(length, minValue, maxValue).ToArray()
  50.        Return Me.valueB
  51.    End Function
  52.  
  53.    Protected Iterator Function GenerateSequenceInternal(ByVal length As Integer, ByVal minValue As Integer, ByVal maxValue As Integer) As IEnumerable(Of Integer)
  54.        For i As Integer = 0 To (length - 1)
  55.            Yield rand.Next(minValue, maxValue)
  56.        Next i
  57.    End Function
  58.  
  59.    Public Overrides Function Equals(ByVal obj As Object) As Boolean
  60.        If (TypeOf obj IsNot RandomSequence) Then
  61.            Return False
  62.        Else
  63.            Return String.Join(" ", Me.valueB).Equals(String.Join(" ", DirectCast(obj, RandomSequence).valueB))
  64.        End If
  65.    End Function
  66.  
  67.    Public Overridable Shadows Function ToString(ByVal formatProvider As IFormatProvider, ByVal format As String) As String
  68.        If (TypeOf formatProvider Is ICustomFormatter) Then
  69.            Return DirectCast(formatProvider, ICustomFormatter).Format(format, Me.valueB, formatProvider)
  70.  
  71.        ElseIf (formatProvider IsNot Nothing) Then
  72.            Return formatProvider.ToString()
  73.  
  74.        Else
  75.            Return Me.valueB.ToString()
  76.  
  77.        End If
  78.    End Function
  79.  
  80.    <EditorBrowsable(EditorBrowsableState.Never)>
  81.    Public Overridable Shadows Function GetHashCode() As Integer
  82.        Return MyBase.GetHashCode()
  83.    End Function
  84.  
  85.    <EditorBrowsable(EditorBrowsableState.Never)>
  86.    Public Overridable Shadows Function [GetType]() As Type
  87.        Return MyBase.GetType()
  88.    End Function
  89.  
  90.    <EditorBrowsable(EditorBrowsableState.Never)>
  91.    Public Shared Shadows Function ReferenceEquals(ByVal objA As Object, ByVal objB As Object) As Boolean
  92.        Return Object.ReferenceEquals(objA, objB)
  93.    End Function
  94.  
  95. End Class

Ejemplo de uso:
Código
  1. Dim seq1 As New RandomSequence(length:=3) ' minValue:=0, maxValue:=Integer.MaxValue
  2. Dim seq2 As New RandomSequence(length:=3, minValue:=0, maxValue:=100)
  3. Dim seq3 As New RandomSequence({1, 2, 3})
  4.  
  5. Console.WriteLine(seq1.Length)
  6. Console.WriteLine(seq1.Equals(seq2))
  7. Console.WriteLine(seq1.Value.ToString())
  8. Console.WriteLine(seq1.Value("Horizontal")) ' o "H"
  9. Console.WriteLine(seq1.Value("Vertical"))   ' o "V"



Seguidamente, definimos un segunto Type donde implementaremos las interfaces IFormatProvider y ICustomFormatter, y así desarrollaremos el algoritmo de formateo para representar en texto horizontal o vertical una secuencia numérica. La gran ventaja de desarrollar nuestro propio proveedor de formato es que se puede adaptar para utilizarlo de mil formas distintas, en cientos de situaciones diferentes.

Código
  1. Public Class IntegerSequenceFormatter : Implements IFormatProvider, ICustomFormatter
  2.  
  3.    Public Function GetFormat(formatType As Type) As Object Implements IFormatProvider.GetFormat
  4.        If formatType Is GetType(ICustomFormatter) Then
  5.            Return Me
  6.        Else
  7.            Return Nothing
  8.        End If
  9.    End Function
  10.  
  11.    Public Function Format(fmt As String, arg As Object, formatProvider As IFormatProvider) As String Implements ICustomFormatter.Format
  12.  
  13.        If Not Me.Equals(formatProvider) Then
  14.            Return Nothing
  15.        End If
  16.  
  17.        If String.IsNullOrEmpty(fmt) Then
  18.            Dim result As Integer() = TryCast(arg, Integer())
  19.            If (result Is Nothing) Then
  20.                Throw New ArgumentException("Value is not of type Integer()", paramName:="arg")
  21.                Exit Function
  22.            End If
  23.        End If
  24.  
  25.        If String.IsNullOrEmpty(fmt) Then
  26.            Throw New ArgumentNullException(paramName:="fmt")
  27.            Exit Function
  28.        End If
  29.  
  30.        Select Case fmt.ToLower()
  31.            Case "h", "horizontal"
  32.                Dim seq As Integer() = DirectCast(arg, Integer())
  33.                Dim maxLength As Integer = CStr(seq.Max()).Length
  34.                Dim sb As New StringBuilder(capacity:=seq.Length * maxLength)
  35.                For Each item As Integer In seq
  36.                    sb.Append(item.ToString().PadLeft(maxLength, "0"c))
  37.                    sb.Append(" "c)
  38.                Next
  39.                Return sb.ToString.TrimEnd(" "c)
  40.  
  41.            Case "v", "vertical"
  42.                Dim seq As Integer() = DirectCast(arg, Integer())
  43.                Dim maxLength As Integer = CStr(seq.Max()).Length
  44.                Dim sb As New StringBuilder(capacity:=seq.Length * maxLength)
  45.                For Each item As Integer In seq
  46.                    sb.AppendLine(item.ToString().PadLeft(maxLength, "0"c))
  47.                Next
  48.                Return sb.ToString()
  49.  
  50.            Case Else
  51.                Throw New FormatException(String.Format("'{0}' cannot be used to format {1}.", fmt, arg.ToString()))
  52.        End Select
  53.  
  54.    End Function
  55.  
  56. End Class

Ejemplo de uso:
Código
  1. Dim arr As Integer() = {1, 2, 3, 4, 5}
  2. Dim strHorz As String = String.Format(New IntegerSequenceFormatter, "{0:H}", arr)
  3. Dim strVert As String = String.Format(New IntegerSequenceFormatter, "{0:V}", arr)
  4.  
  5. Console.WriteLine(strHorz)
  6. Console.WriteLine(strVert)

Nota:
En el el type RandomSequence no necesitaremos utilizarlo pasando tantos argumentos, lo acortaremos a RandomSequence.Value("H") y RandomSequence.Value("V").



Por último, solo nos queda hacer uso de todo esto para construir la tabla y representarla en el control DataGridView:

Código
  1. Public Class Form1 : Inherits Form
  2.  
  3.    Dim seqList As New List(Of RandomSequence)
  4.    Dim seqTable As New DataTable("RandomSequenceTable")
  5.  
  6.    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
  7.  
  8.        Dim seqCount As Integer = 20 ' Amount of random sequences to generate.
  9.  
  10.        ' Build random sequences list. This is optional, just to have a short reference to a generic collection in source-code.
  11.        For i As Integer = 0 To (seqCount - 1)
  12.            seqList.Add(New RandomSequence(length:=16, minValue:=0, maxValue:=16))
  13.        Next
  14.  
  15.        ' Build table from list.
  16.        For x As Integer = 0 To (seqList.Count - 1)
  17.            seqTable.Columns.Add(New DataColumn)
  18.            seqTable.Columns(x).DataType = GetType(RandomSequence)
  19.        Next
  20.        seqTable.Rows.Add.ItemArray = seqList.ToArray()
  21.        ' To build a data-table of vertical strings representation:
  22.        ' seqTable.Rows.Add.ItemArray = (From seq As RandomSequence In seqList Select seq.Value("V")).ToArray()
  23.        seqTable.AcceptChanges()
  24.  
  25.        ' Build grid.
  26.        DataGridView1.SuspendLayout()
  27.        With DataGridView1
  28.            .AllowUserToAddRows = False
  29.            .AllowUserToResizeColumns = False
  30.            .AutoGenerateColumns = True
  31.            .AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.DisplayedCells
  32.            .AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.DisplayedCells
  33.            .ClipboardCopyMode = DataGridViewClipboardCopyMode.EnableWithoutHeaderText
  34.            .ColumnHeadersVisible = False
  35.            .DefaultCellStyle.Padding = New Padding(5, 2, 5, 2)
  36.            .DefaultCellStyle.WrapMode = DataGridViewTriState.True
  37.            .MultiSelect = True
  38.            .ReadOnly = True
  39.            .RowHeadersVisible = False
  40.            .RowsDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter
  41.            .Size = New Size(New Point(400, 240))
  42.        End With
  43.        DataGridView1.DataSource = seqTable
  44.        DataGridView1.ResumeLayout()
  45.  
  46.    End Sub
  47.  
  48.    Private Sub DataGridView1_CellFormatting(ByVal sender As Object, ByVal e As DataGridViewCellFormattingEventArgs) _
  49.    Handles DataGridView1.CellFormatting
  50.  
  51.        If (e.Value IsNot Nothing) Then
  52.            Dim item As RandomSequence = TryCast(e.Value, RandomSequence)
  53.            If (item IsNot Nothing) Then
  54.                e.Value = item.Value("Vertical")
  55.            End If
  56.        End If
  57.  
  58.    End Sub
  59.  
  60. End Class

Nótese que el contenido de las celdas se formatean controlando el evento DataGridView1.CellFormatting, esto es algo ilustrativo y opcional, se puede contruir la data-table con las celdas ya formateadas para no tener que hacerlo después controlando ese evento, pero veo de mayor utilidad tener un data-table de RandomSequence, que de Strings multilinea...



Resultado de ejecución:



Saludos!
« Última modificación: 13 Diciembre 2016, 15:34 pm por Eleкtro » En línea

Páginas: [1] 2 Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
salto de línea en ficheros
Programación Visual Basic
AGRIPI 1 2,034 Último mensaje 25 Mayo 2006, 15:06 pm
por sch3m4
Salto de linea en Batch
Scripting
Jatt 2 13,080 Último mensaje 5 Enero 2007, 18:55 pm
por Jatt
¿Borrar linea 1 de textbox multilinea y que la 2ª, suba a la primera?
.NET (C#, VB.NET, ASP)
usuario oculto 5 10,196 Último mensaje 4 Agosto 2011, 19:48 pm
por usuario oculto
Salto de línea
Desarrollo Web
bgnumis 2 3,847 Último mensaje 25 Junio 2018, 19:49 pm
por JUCA
Extraer determinada linea de un textbox multilinea
Programación Visual Basic
rapbyone 1 3,058 Último mensaje 6 Diciembre 2019, 20:50 pm
por Serapis
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines