none
WinForm / Listview : mise à jour contenu automatiquement à partir d'une source objet RRS feed

  • Discussion générale

  • Bonjour,

    J'ai pour habitude professionnellement de faire du webform et donc là je bute sur un problème qui me déroute sous du winform.

    Je vais essayé d'être le plus clair possible.

    Dans un winForm j'ai d'un côté j'ai un listview vide et un bouton d'action

    Dans un autre projet, des fichiers de classes qui vont avoir différentes entrées publiques

    J'ai ma classe principale qui contient un list(Of objectA)

    ObjectA contient le nom d'un répertoire par exemple pour le moment mais contiendra d'autres détails qui pourront être généré par exemple lors d'un appel via un autre bouton dans le formulaire par exemple. (exemple aller lister le détail du répertoire)
    Imaginons un scan de répertoire listant que ses sous répertoire de 1er niveau (lent, pour simuler un traitement long)
    Je voudrais que ma listview se mettent automatiquement à jour 

    Exemple un répertoire est retrouvé hop il apparaît dans le listview

    Ainsi de suite, sans bloquer l'interface

    Puis pendant ce temps je cliquerais sur le 2ème futur bouton et ça générerais donc le listing dans l'objectA les différents fichier contenue et afficherais dans le listview le nombre de fichier dans une colonne à côté du nom du répertoire. toujours sans bloquer l'interface.

    C'est cette mécanique complexe que je voudrais mettre en oeuvre ayant réalisé les différentes choses indépendamment, pour dissocié interface et traitement(DLL).

    il ne s'agit pas de simple scan de répertoire, j'ai volontairement réduit à ceci pour expliquer le concept.

    Merci d'avance pour votre aide.

    mercredi 6 juillet 2016 16:48

Toutes les réponses

  • Bonjour,

    Vous avez plein de façon de faire (évènements, action, etc.). Un exemple :

            private bool _isRunning;
            private void button1_Click(object sender, EventArgs e)
            {
                if (_isRunning) return;
                _isRunning = true;
                Task.Run(async () =>
                {
                    AddItem("premier item");
                    await Task.Delay(5000);
                    AddItem("second item");
                    await Task.Delay(5000);
                    AddItem("troisième item");
                    _isRunning = false;
                });
            }
    
            private void AddItem(string item)
            {
                BeginInvoke(new Action<string>(e =>
                {
                    listView1.Items.Add(e);
                }), item);
            }


    Richard Clark
    Consultant - Formateur .NET
    http://www.c2i.fr
    Depuis 1996: le 1er site .NET francophone

    jeudi 7 juillet 2016 09:34
  • Bonjour,

    Merci pour votre réponse.

    J'ai converti votre code pour vb.net, il marche et je comprends bien le principe, le problème c'est que je voudrais l'appliqué à une liste qui se trouve contenu dans un objet qui grandie et change entre temps, je voudrais que ce soit répercuté dans le listview sans pour autant bloqué l'utilisateur durant le traitement.

    J'ai simulé dans l'exemple ci dessous le traitement par le clic sur le "bouton2" (bien sur ici il faut attendre la fin)

    C'est un peut comme un logiciel "torrent" dans lequel l'on a des lignes qui sont mis à jour sans arrêt, ou ajouter. que je voudrais faire.

    Public Class Form1
    
        Private _isRunning As Boolean
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    
            If (_isRunning) Then Exit Sub
    
            _isRunning = True
            Task.Run(Async Function()
                         AddItem("premier item")
                         Await Task.Delay(5000)
                         AddItem("second item")
                         Await Task.Delay(5000)
                         AddItem("troisième item")
                         _isRunning = False
                     End Function)
    
        End Sub
    
        Private Sub AddItem(item As String)
            BeginInvoke(New Action(Of String)(Function(e)
                                                  ListView1.Items.Add(e)
                                              End Function), item)
        End Sub
    
    
        Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
    
            Dim monObj As New GetElement
            monObj.Execute()
    
        End Sub
    End Class
    
    Public Class GetElement
    
        Private _elementList As New List(Of String)
        Public ReadOnly Property ElementList As List(Of String)
            Get
                Return _elementList
            End Get
        End Property
    
    
        Public Sub Execute()
    
            _elementList.Clear()
            For i As Integer = 0 To 50 - 1
                _elementList.Add("Execute " & i.ToString)
                System.Threading.Thread.Sleep(500)
    
                If (i Mod 2) = 0 Then ChangeRandomElement()
            Next
        End Sub
    
        Public Sub ChangeRandomElement()
    
            Dim nbElement As Integer = _elementList.Count
    
            If nbElement - 1 > 0 Then
                Dim numElement As Integer = GetRandomNum(nbElement - 1)
                _elementList(numElement) = "Changed " & numElement.ToString
            End If
    
        End Sub
    
        Private Function GetRandomNum(max As Integer) As Integer
            Dim number As Integer
    
            Randomize()
            number = Int(Rnd() * max) + 1
    
            Return number
        End Function
    
    
    End Class

    Merci de votre aide.

    jeudi 7 juillet 2016 11:44