Hola
Hacía tiempo que no programaba con vb.net pero hoy me he puesto.
He creado un objeto ListView, le he puesto tres cabeceras (headers) y resulta que cuando quiero añadir un valor a una una celda me da error. Antes debo haber introducido algo mediante ADD, y luego si que puedo. ¿Esto porqué ocurre? Me parece una tontería. No se si es que hago un mal uso del objeto.
Aquí un ejemplo donde primero y para evitar el error, debo añadir un valor nulo mediante Add y después introduzco el valor TEXT a la celda.
ListView1.Items(0).SubItems.Add("")
ListView1.Items(0).SubItems(0).Text = "hola mundo"
Me da la impresión de que add, lo que hace es crear la celda, y no puedes cambiarle el valor text hasta que no esté creada.
Pero la cosa es que si has creado tres columnas y as añadido un valor a la primera celda de la primera columna, me parece tedioso tener que crear la celda siguiente de la siguiente columna correspondiente a la primera celda, que ya tiene un valor en la primera celda.
Cita de: okik en 19 Enero 2019, 12:18 PMMe da la impresión de que add, lo que hace es crear la celda, y no puedes cambiarle el valor text hasta que no esté creada.
Tu mismo te has respondido a la pregunta, aunque sería más correcto decir que el método
ListViewSubItemCollection.Add() crea un nuevo elemento en la colección, y luego el
ListView genera la representación visual de la forma en que lo hace.
Cita de: okik en 19 Enero 2019, 12:18 PM¿Esto porqué ocurre? Me parece una tontería.
Lo que te parece una tontería, no tendría sentido que fuese de otra forma.
Recapitulemos:
Cuando llamas al método SubItems.Add, estás creando un nuevo subitem...
CitarListView1.Items(0).SubItems.Add("")
y luego, como es lógico, puedes acceder a él mediante el indexer de la colección de subitems...
CitarListView1.Items(0).SubItems(0).Text = "hola mundo"
Sinceramente, me cuesta entender que otro comportamiento distinto esperas que tenga. Por lo que creo entender, ¿pretendes poder escribir por ejemplo ListView1.Items(14).SubItems(85).Text y que se generen automaticamente los items de 0 al 14 y los subitems del 0 al 85?, eso si que no tendría sentido, piénsalo bien, jeje. Para acceder a un item o subitem mediante el indexer, el item o subitem en cuestión debe existir por haberlo creado antes mediante el método b de la colección en cuestión...
Cita de: okik en 19 Enero 2019, 12:18 PMPero la cosa es que si has creado tres columnas y as añadido un valor a la primera celda de la primera columna, me parece tedioso tener que crear la celda siguiente de la siguiente columna correspondiente a la primera celda, que ya tiene un valor en la primera celda.
Entiendo que su utilización te resulte un procedimientos tedioso, pero eso es lo que conlleva la forma en la que estás haciendo las cosas.
Puedes simplificar bastante el procedimiento, especificando todos los items/celdas que quieras mediante el constructor de la clase
ListViewItem, tal que así:
Dim lvi As New ListViewItem({"item1", "item2", "item3"})
Me.ListView1.Items.Add(lvi)
O bien en lugar de usar un control de tipo
ListView puedes usar un
DataGridView y simplificar al máximo la adición de elementos mediante sus capacidades de enlace de datos (usando la propiedad
DataGridView.DataSource).
Saludos.
Gracias Eleкtro (sin pilas).
Pues eso no hay otra que crear el elemento en la colección antes.
Claro y es que yo supongo no puedo evitar interpretarlo como un DataGridView. Es que yo le he dado a la propiedad GridLines como True. Esto hace que visualmente tenga aspecto de DataGridView. Sin embargo desde código las celdas son inexistentes, ya que no son celdas realmente si no elementos de una colección como tu dices. Pero creo no voy mal encaminado de que se pudiera establecer una propiedad similar a un DataGridView, en cuanto a las "celdas" del Listview. Si creo tres columnas y creo un elemento de la colección mediante ADD, los elementos subitems de la misma file deberían crearse automáticamente.
Saludos
Cita de: okik en 19 Enero 2019, 21:56 PMPero creo no voy mal encaminado de que se pudiera establecer una propiedad similar a un DataGridView, en cuanto a las "celdas" del Listview.
Hay un problema con ese tipo de pensamiento, y es que estás viendo el control
ListView como si fuese similar a un
DataGridView, a modo de columnas y celdas, pero el control
ListView tiene varias vistas distintas, entre ellas la de tipo tabla/grid (más conocida como vista de detalles), sí, pero el control
ListView no necesariamente tiene por que tener columnas creadas, y además, no hay límite de subitems que puedes crear para un item (más allá de los límites virtuales de memoria) indiferentemente de la cantidad de columnas que se haya creado, y estos subitems solo serán representados visualmente si el control tiene columnas creadas. Por estos motivos, pretender que automaticamente exista la misma cantidad de subitems que de columnas no tiene mucho sentido, ni aun usando la vista de detalles...
Cita de: okik en 19 Enero 2019, 21:56 PMSi creo tres columnas y creo un elemento de la colección mediante ADD, los elementos subitems de la misma file deberían crearse automáticamente.
Desde el primer momento te he dejado clara mi postura: esto me parece totalmente innecesario. Pero si quieres seguir con este enfoque, y por no dejarte sin una respuesta que te resulte satisfactoria pues aquí te muestro una solución que escrito donde implemento un
ListView personalizado en el que sustituyo la colección base de items por una colección personalizada en la que reimplemento las funciones "Add" que se encargan de añadir el item en la colección...
<DisplayName(NameOf(CustomListView))>
<Description("A custom ListView control.")>
<DesignTimeVisible(True)>
<DesignerCategory(NameOf(DesignerCategoryAttribute.Default))>
<ToolboxBitmap(GetType(ListView), "ListView.bmp")>
<ToolboxItemFilter("System.Windows.Forms", ToolboxItemFilterType.Require)>
<ClassInterface(ClassInterfaceType.AutoDispatch)>
<ComVisible(True)>
<DefaultProperty(NameOf(CustomListView.Items))>
<DefaultEvent(NameOf(CustomListView.SelectedIndexChanged))>
<Docking(DockingBehavior.Ask)>
<PermissionSet(SecurityAction.Demand, Name:="FullTrust")>
Public Class CustomListView : Inherits ListView
<DisplayName(NameOf(CustomListView.Items))>
<Description("The items in the ListView")>
<DesignerSerializationVisibility(DesignerSerializationVisibility.Content)>
<Localizable(True)>
<MergableProperty(False)>
<Browsable(True)>
Public Shadows ReadOnly Property Items As CustomListViewItemCollection
Public Sub New()
MyBase.New()
Me.Items = New CustomListViewItemCollection(Me)
End Sub
End Class
<DefaultMember("Item")>
<ListBindable(False)>
Public Class CustomListViewItemCollection : Inherits ListViewItemCollection
Private ReadOnly owner As ListView
Public Sub New(owner As ListView)
MyBase.New(owner)
Me.owner = owner
End Sub
Public Overrides Function Add(value As ListViewItem) As ListViewItem
Return Me.CreateAllSubItems(MyBase.Add(value))
End Function
<DebuggerStepThrough>
Private Function CreateAllSubItems(value As ListViewItem) As ListViewItem
Dim diff As Integer = (Me.owner.Columns.Count - value.SubItems.Count)
If (diff > 0) Then
For i As Integer = 0 To (diff - 1)
value.SubItems.Add(String.Empty)
Next i
End If
Return value
End Function
End Class
Modo de empleo:
Me.CustomListView1.View = System.Windows.Forms.View.Details
' Creamos 5 columnas.
For i As Integer = 1 To 5
Me.CustomListView1.Columns.Add(String.Format("Column {0}", i))
Next i
' Añadimos un item donde se crearán subitems o "celdas" vacías para las cinco columnas.
Me.CustomListView1.Items.Add("")
' Especificamos los valores de los cinco subitems
' sin necesidad de haber llamado al método SubItems.Add() para cada uno de ellos...
Me.CustomListView1.Items(0).SubItems(0).Text = "Value 1"
Me.CustomListView1.Items(0).SubItems(1).Text = "Value 2"
Me.CustomListView1.Items(0).SubItems(2).Text = "Value 3"
Me.CustomListView1.Items(0).SubItems(3).Text = "Value 4"
Me.CustomListView1.Items(0).SubItems(4).Text = "Value 5"
(https://i.imgur.com/Pv1rLyr.png)
Esa sería la idea, ahora, el comportamiento que debería tener la clase
CustomListView al eliminar una columna o añadir una nueva despues de que un item ya haya sido añadido, sería cosa tuya.
Saludos.
Cita de: Eleкtro (sin pilas) en 20 Enero 2019, 01:51 AM
reimplemento las funciones "Add" que se encargan de añadir el item en la colección...
Vaya, eso no lo sabía hacer yo... :-\
Bueno gracias, eso justo sería lo que digo.