Estoy intentando hacer una manera para recuperar los items de un listview si la aplicación se cierra o se mata indebídamente.
El listview está en modo "detalles" y tiene 3 columnas.
Para guardar los items, hago esto:
Dim Recovery_Items As New List(Of Tuple(Of Integer, String, String))()
Private Sub Recovery_Timer_Tick() Handles Recovery_Timer.Tick
Recovery_Items.Clear()
For Each item As ListViewItem In ListView_Monitor.Items
Recovery_Items.Add(Tuple.Create(item.Index, item.SubItems(1).Text, item.SubItems(2).Text))
Next
IO.File.WriteAllText("Recovery.tmp", String.Join(vbNewLine, Recovery_Items), System.Text.Encoding.Default)
End Sub
...Lo cual me genera esto en un archivo de texto:
(0, Valor1, Valor2)
(1, V-a-l-o-r-1, V-a-l-o-r-2)
(2, V,a,l,o,r,1, V,a,l,o,r,2)
Ahora, ¿Como puedo parsear/castear el contenido del archivo de texto para agregarlo como item del listview en sus respectivas columnas?
Un ejemplo de lo que intento hacer, esto sucedería al iniciar la aplicación:
Private Sub Recovery()
If IO.File.Exists("Recovery.tmp") Then
For Each Line As String In IO.File.ReadAllLines("Recovery.tmp")
ListView_Monitor.Items.Add(TryCast(Line, ListViewItem))
Next
End If
End Sub
Pero claro... al contener tantas comas los valores, no puedo hacer un Split, ni se me ocurre nada que hacer.
Estoy saliendo del apuro haciéndolo de la siguiente manera, pero me parece muy cutre y segúramente se puede mejorar mucho...
Guardar:
Dim Recovery_Items As New List(Of Tuple(Of Integer, String, String))()
' Recovery Timer
Private Sub Recovery_Timer_Tick() Handles Recovery_Timer.Tick
Recovery_Items.Clear()
For Each item As ListViewItem In ListView_Monitor.Items
Recovery_Items.Add(Tuple.Create( _
item.Index, _
String.Format("""""{0}""""", item.SubItems(1).Text), _
String.Format("""""{0}""""", item.SubItems(2).Text)))
Next
IO.File.WriteAllText("Recovery.tmp", String.Join(vbNewLine, Recovery_Items), System.Text.Encoding.ASCII)
End Sub
Archivo de texto:
(0, "Valor1", "Valor2")
(1, "V,a,l,o,r,1", "V,a,l,o,r,2")
Cargar:
Dim Recovery_Index As Integer = 0
Private Sub Recovery()
If IO.File.Exists("Recovery.tmp") Then
For Each Line As String In IO.File.ReadAllLines("Recovery.tmp")
Line = Line.Substring(1, Line.Length - 2) ' Deletes the first and last () chars.
For Each value As String In Line.Split(", """)
Recovery_Index += 1
Select Case Recovery_Index
Case 1
item = ListView_Monitor.AddItem(value.Replace("""", Nothing).Trim)
Case Else
item.SubItems.Add(value.Replace("""", Nothing).Trim)
End Select
Next
Recovery_Index = 0
Next
End If
End Sub
Guardar
List<ListViewItem> items = new List<ListViewItem>();
foreach (ListViewItem listView in listView1.Items)
{
items.Add(listView);
}
BinaryFormatter binary = new BinaryFormatter();
using (FileStream sw = new FileStream(@"D:\listItems.dat",FileMode.Create))
{
binary.Serialize(sw, items);
}
Cargar
listView1.Items.Clear();
List<ListViewItem> items;
BinaryFormatter binary = new BinaryFormatter();
using (FileStream sr = new FileStream(@"D:\listItems.dat",FileMode.Open))
{
items = (List<ListViewItem>)binary.Deserialize(sr);
}
listView1.Items.AddRange(items.ToArray());
Saludos
Muchas gracias!
Edito:
Así queda el código para VB
#Region " Backup and Recovery Listview Items "
' [ Backup and Recovery Listview Items ]
ReadOnly BackupFile As String = "Recovery.tmp" ' File conaining the data to recover.
Private BackupData As New List(Of ListViewItem) ' Storage for the data to backup.
Private BinaryFormat As New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter()
Private Sub Backup(ByVal ListView As ListView)
BackupData.Clear()
Select Case ListView.Items.Count
Case 0
Try : IO.File.Delete(BackupFile) : Catch : End Try
' We don't need the BackupFile if it will not contains anything to recover...
Case Else
BackupData.AddRange(ListView.Items.Cast(Of ListViewItem))
Using Writter As New IO.FileStream(BackupFile, IO.FileMode.Create)
BinaryFormat.Serialize(Writter, BackupData)
End Using
End Select
End Sub
Private Sub Recovery(ByVal ListView As ListView)
If IO.File.Exists(BackupFile) Then
Using Reader As New IO.FileStream(BackupFile, IO.FileMode.Open)
BackupData = DirectCast(BinaryFormat.Deserialize(Reader), List(Of ListViewItem))
End Using
ListView.Items.AddRange(BackupData.ToArray())
End If
End Sub
#End Region