2016-03-07 3 views
1

Je crée une liste de contacts avec VB.NET avec des images d'état. Je charge cette liste depuis MSSQL mais quand je recharge la liste, elle scintille.Modifier l'image à partir d'une image dynamique multiple

Cette liste est un TableLayoutPanel avec des vues dynamiques et des étiquettes créées.

Ma question est:

Comment puis-je changer mon image à l'intérieur d'un picturebox dynamique lorsque u rechargent mes contacts au lieu de recharger la liste complète.

Mon code pour créer la table:

While UserData.Read 

    If UserData("Status").ToString = "Online" Then 

     If UserData("NieuwBericht").ToString = "Ja" Then 

      Dim newPictureBox As New PictureBox 
      newPictureBox.Image = My.Resources.greenchat 
      newPictureBox.Visible = True 
      newPictureBox.Width = 30 
      newPictureBox.Height = 30 
      newPictureBox.SizeMode = PictureBoxSizeMode.Zoom 
      newPictureBox.Name = UserData("Username").ToString 
      ChatContactList.Controls.Add(newPictureBox) 

      Dim newPictureBox2 As New PictureBox 
      newPictureBox2.Image = My.Resources.greenbubblechat 
      newPictureBox2.Visible = True 
      newPictureBox2.Width = 30 
      newPictureBox2.Height = 30 
      newPictureBox2.SizeMode = PictureBoxSizeMode.Zoom 
      newPictureBox2.Name = UserData("Username").ToString 
      ChatContactList.Controls.Add(newPictureBox2) 

      Dim newLabel As New Label 
      AddHandler newLabel.Click, AddressOf Chatbox 
      newLabel.Text = UserData("Voornaam").ToString & " " & UserData("Achternaam").ToString 
      newLabel.Name = UserData("Username").ToString 
      newLabel.Font = New Font("Microsoft sans serif", 12) 
      newLabel.Dock = DockStyle.Fill 
      newLabel.TextAlign = ContentAlignment.MiddleLeft 
      newLabel.Visible = True 
      ChatContactList.Controls.Add(newLabel) 

     ElseIf UserData("NieuwBericht").ToString = "Nee" Then 

      Dim newPictureBox As New PictureBox 
      newPictureBox.Image = My.Resources.greenchat 
      newPictureBox.Visible = True 
      newPictureBox.Width = 30 
      newPictureBox.Height = 30 
      newPictureBox.SizeMode = PictureBoxSizeMode.Zoom 
      newPictureBox.Name = UserData("Username").ToString 
      ChatContactList.Controls.Add(newPictureBox) 

      Dim newPictureBox2 As New PictureBox 
      newPictureBox2.Image = My.Resources.greybubblechat 
      newPictureBox2.Visible = True 
      newPictureBox2.Width = 30 
      newPictureBox2.Height = 30 
      newPictureBox2.SizeMode = PictureBoxSizeMode.Zoom 
      newPictureBox2.Name = UserData("Username").ToString 
      ChatContactList.Controls.Add(newPictureBox2) 

      Dim newLabel As New Label 
      AddHandler newLabel.Click, AddressOf Chatbox 
      newLabel.Text = UserData("Voornaam").ToString & " " & UserData("Achternaam").ToString 
      newLabel.Name = UserData("Username").ToString 
      newLabel.Font = New Font("Microsoft sans serif", 12) 
      newLabel.Dock = DockStyle.Fill 
      newLabel.TextAlign = ContentAlignment.MiddleLeft 
      newLabel.Visible = True 
      ChatContactList.Controls.Add(newLabel) 

     End If 

    ElseIf UserData("Status").ToString = "Afwezig" Then 

     If UserData("NieuwBericht").ToString = "Ja" Then 

      Dim newPictureBox As New PictureBox 
      newPictureBox.Image = My.Resources.orangechat 
      newPictureBox.Visible = True 
      newPictureBox.Width = 30 
      newPictureBox.Height = 30 
      newPictureBox.SizeMode = PictureBoxSizeMode.Zoom 
      newPictureBox.Name = UserData("Username").ToString 
      ChatContactList.Controls.Add(newPictureBox) 

      Dim newPictureBox2 As New PictureBox 
      newPictureBox2.Image = My.Resources.greenbubblechat 
      newPictureBox2.Visible = True 
      newPictureBox2.Width = 30 
      newPictureBox2.Height = 30 
      newPictureBox2.SizeMode = PictureBoxSizeMode.Zoom 
      newPictureBox2.Name = UserData("Username").ToString 
      ChatContactList.Controls.Add(newPictureBox2) 

      Dim newLabel As New Label 
      AddHandler newLabel.Click, AddressOf Chatbox 
      newLabel.Text = UserData("Voornaam").ToString & " " & UserData("Achternaam").ToString 
      newLabel.Name = UserData("Username").ToString 
      newLabel.Font = New Font("Microsoft sans serif", 12) 
      newLabel.Dock = DockStyle.Fill 
      newLabel.TextAlign = ContentAlignment.MiddleLeft 
      newLabel.Visible = True 
      ChatContactList.Controls.Add(newLabel) 

     ElseIf UserData("NieuwBericht").ToString = "Nee" Then 

      Dim newPictureBox As New PictureBox 
      newPictureBox.Image = My.Resources.orangechat 
      newPictureBox.Visible = True 
      newPictureBox.Width = 30 
      newPictureBox.Height = 30 
      newPictureBox.SizeMode = PictureBoxSizeMode.Zoom 
      newPictureBox.Name = UserData("Username").ToString 
      ChatContactList.Controls.Add(newPictureBox) 

      Dim newPictureBox2 As New PictureBox 
      newPictureBox2.Image = My.Resources.greybubblechat 
      newPictureBox2.Visible = True 
      newPictureBox2.Width = 30 
      newPictureBox2.Height = 30 
      newPictureBox2.SizeMode = PictureBoxSizeMode.Zoom 
      newPictureBox2.Name = UserData("Username").ToString 
      ChatContactList.Controls.Add(newPictureBox2) 

      Dim newLabel As New Label 
      AddHandler newLabel.Click, AddressOf Chatbox 
      newLabel.Text = UserData("Voornaam").ToString & " " & UserData("Achternaam").ToString 
      newLabel.Name = UserData("Username").ToString 
      newLabel.Font = New Font("Microsoft sans serif", 12) 
      newLabel.Dock = DockStyle.Fill 
      newLabel.TextAlign = ContentAlignment.MiddleLeft 
      newLabel.Visible = True 
      ChatContactList.Controls.Add(newLabel) 

     End If 

    ElseIf UserData("Status").ToString = "Offline" Then 

     If UserData("NieuwBericht").ToString = "Ja" Then 

      Dim newPictureBox As New PictureBox 
      newPictureBox.Image = My.Resources.redchat 
      newPictureBox.Visible = True 
      newPictureBox.Width = 30 
      newPictureBox.Height = 30 
      newPictureBox.SizeMode = PictureBoxSizeMode.Zoom 
      newPictureBox.Name = UserData("Username").ToString 
      ChatContactList.Controls.Add(newPictureBox) 

      Dim newPictureBox2 As New PictureBox 
      newPictureBox2.Image = My.Resources.greenbubblechat 
      newPictureBox2.Visible = True 
      newPictureBox2.Width = 30 
      newPictureBox2.Height = 30 
      newPictureBox2.SizeMode = PictureBoxSizeMode.Zoom 
      newPictureBox2.Name = UserData("Username").ToString 
      ChatContactList.Controls.Add(newPictureBox2) 

      Dim newLabel As New Label 
      AddHandler newLabel.Click, AddressOf Chatbox 
      newLabel.Text = UserData("Voornaam").ToString & " " & UserData("Achternaam").ToString 
      newLabel.Name = UserData("Username").ToString 
      newLabel.Font = New Font("Microsoft sans serif", 12) 
      newLabel.Dock = DockStyle.Fill 
      newLabel.TextAlign = ContentAlignment.MiddleLeft 
      newLabel.Visible = True 
      ChatContactList.Controls.Add(newLabel) 

     ElseIf UserData("NieuwBericht").ToString = "Nee" Then 

      Dim newPictureBox As New PictureBox 
      newPictureBox.Image = My.Resources.redchat 
      newPictureBox.Visible = True 
      newPictureBox.Width = 30 
      newPictureBox.Height = 30 
      newPictureBox.SizeMode = PictureBoxSizeMode.Zoom 
      newPictureBox.Name = UserData("Username").ToString 
      ChatContactList.Controls.Add(newPictureBox) 

      Dim newPictureBox2 As New PictureBox 
      newPictureBox2.Image = My.Resources.greybubblechat 
      newPictureBox2.Visible = True 
      newPictureBox2.Width = 30 
      newPictureBox2.Height = 30 
      newPictureBox2.SizeMode = PictureBoxSizeMode.Zoom 
      newPictureBox2.Name = UserData("Username").ToString 
      ChatContactList.Controls.Add(newPictureBox2) 

      Dim newLabel As New Label 
      AddHandler newLabel.Click, AddressOf Chatbox 
      newLabel.Text = UserData("Voornaam").ToString & " " & UserData("Achternaam").ToString 
      newLabel.Name = UserData("Username").ToString 
      newLabel.Font = New Font("Microsoft sans serif", 12) 
      newLabel.Dock = DockStyle.Fill 
      newLabel.TextAlign = ContentAlignment.MiddleLeft 
      newLabel.Visible = True 
      ChatContactList.Controls.Add(newLabel) 

     End If 

    End If 

End While 

Image de mon contactlist

enter image description here

+0

Intéressant. Je me souviens avoir suggéré un contrôle de l'utilisateur lorsque vous avez posté il y a un peu de temps. Si vous avez un contrôle utilisateur, vous pouvez gérer ce genre de choses plus facilement ... Ensuite, vous pouvez écrire des méthodes pour gérer n'importe lequel d'entre eux ... Cela signifie que vous devez créer un contrôle utilisateur qui hébergerait tout ce qui concerne cette personne ... pourquoi votre code ci-dessus est long et demande des ennuis. Tout ce qui précède pourrait être réduit de moitié et plus. – Codexer

+0

Voici mon commentaire si vous avez oublié. http://stackoverflow.com/questions/35722326/chat-contact-list-vb-net-and-mssql – Codexer

+0

Je suis d'accord avec @Codexer, et je ne suis pas friand de UserControls à la place des contrôles personnalisés. En l'état, votre formulaire est juste un groupe de contrôles indépendants montrant des informations connexes. – Plutonix

Répondre

2

Un UserControl est un peu comme un sous-formulaire. C'est un conteneur pour un assortiment de contrôles qui agissent ensemble ou représentent une unité logique. Dans ce cas, ce serait la représentation visuelle de certains états utilisateurs (propriétés). Plutôt que de créer et de gérer contrôles individuels, vous pouvez les mettre sur un UC et encapsuler beaucoup du code pour les gérer.

Dans la fenêtre de l'Explorateur de solutions , clic droit, sélectionnez Ajouter , puis choisissez UserControl. J'ai ajouté un TableLayoutPanel, 2 PictureBoxes et un Label (tous avec des noms propres bien sûr). Il y a aussi un ImageList avec un grab rapide de vos images :

enter image description here

Cette seule remplace beaucoup de lignes de code que vous devez créer de nouveaux contrôles, puis définir les mêmes propriétés encore et encore . Pour les faire agir comme un objet logique, vous pouvez ajouter des propriétés qui résumés les menus détails de la sélection d'images etc:

Public Class Chatter 

    Public Enum ChatStatus 
     Unknown 
     Online 
     Away 
     Offline 
    End Enum 

    Public Enum ChatMsgStatus 
     Undefined  ' kludge to force the initial state 
     Unknown 
     [New] 
     Read 
    End Enum 

    ' one set of images for all chatter instances 
    Private Shared Imgs As Image() 

    Public Property ChatId As Int32   ' or guid? 

    Private chName As String = "" 
    Public ReadOnly Property ChatName As String 
     Get 
      Return chName 
     End Get 
    End Property 

    Private mStatus As ChatMsgStatus = ChatMsgStatus.Undefined 
    Public Property MsgStatus As ChatMsgStatus 
     Get 
      Return mStatus 
     End Get 
     Set(value As ChatMsgStatus) 
      If (value <> mStatus) Then 
       Select Case value 
        Case ChatMsgStatus.New 
         pbMStatus.Image = Imgs(3) 
        Case ChatMsgStatus.Read 
         pbMStatus.Image = Imgs(4) 
        Case Else 
         pbMStatus.Image = Imgs(4) 
       End Select 
      End If 
      mStatus = value 
     End Set 
    End Property 

    Private chStatus As ChatStatus = ChatStatus.Unknown 
    Public Property Status As ChatStatus 
     Get 
      Return chStatus 
     End Get 
     Set(value As ChatStatus) 
      If value <> chStatus Then 
       Select Case value 
        Case ChatStatus.Online 
         pbUStatus.Image = Imgs(0) 
        Case ChatStatus.Away 
         pbUStatus.Image = Imgs(1) 
        Case ChatStatus.Offline 
         pbUStatus.Image = Imgs(2) 
        Case Else 
       End Select 
      End If 
      chStatus = value 
     End Set 
    End Property 

    Public Sub New() 
     ' This call is required by the designer. 
     InitializeComponent() 

     If Imgs Is Nothing Then 
      Imgs = New Image() {My.Resources.ChatUserGrn, My.Resources.ChatUserYlw, 
       My.Resources.ChatUserRed, My.Resources.ChatBalloonGrn, 
       My.Resources.ChatBalloonGry} 

       ' see note 
     End If 
    End If 
     ' Add any initialization after the InitializeComponent() call. 
    End Sub 
    ' no need to create one without Identifiers 
    Public Sub New(n As Int32, cname As String) 
     MyClass.New() 
     ' default intitial values: 
     chName = cname 
     ChatId = n 

     lblChName.Text = cname 
     Me.Status = ChatStatus.Online 
     Me.MsgStatus = ChatMsgStatus.Unknown 
    End Sub 
End Class 

(Edit) ne me plaisait pas le résultat en utilisant un ImageList. Cette version, charge un tableau d'images à partir de ressources. En plus de ne charger qu'une seule copie de GreenUser à l'usage de tous les utilisateurs, il vous permet de l'adapter au besoin. Par exemple, remplacez la couleur de fond par SystemColors.Window pour qu'elle corresponde au thème de l'utilisateur. Si vous utilisez également une étiquette au lieu d'une zone d'image, vous pouvez utiliser la propriété Text pour "?" ou même indiquer le numéro de nouveaux messages.

Je suis sûr qu'il ya plus à elle et je peux penser à plusieurs choses Je voudrais qu'il sache (par exemple recouvrir le ballon vert avec le nombre de messages non lus). Mais le point ici sont les concepts d'encapsulation, DRY et le code réutilisable. Lorsque vous le compilerez, un nouveau contrôle Chatter sera ajouté à la boîte à outils.Ajoutez-en lors de l'exécution en utilisant les propriétés exposées:

Dim c As New Chatter(42, "Ziggy von Hausen") 
flpChat.Controls.Add(c) 

c = New Chatter(14, "ThDutoit") 
c.MsgStatus = Chatter.ChatMsgStatus.New 
flpChat.Controls.Add(c) 

c = New Chatter(78, "Plutonix") 
c.Status = Chatter.ChatStatus.Offline 
flpChat.Controls.Add(c) 

c = New Chatter(4, "Codexer") 
c.MsgStatus = Chatter.ChatMsgStatus.New 
c.Status = Chatter.ChatStatus.Away 
flpChat.Controls.Add(c) 

L'identifiant serait quelque chose permettant d'identifier chaque participant de façon unique. Le nom n'est généralement pas suffisant (SO a plus de 50 pages of people named "Steve") et vous voulez un moyen d'identifier pour lier un contrôle à un utilisateur. (Une alternative serait une référence ChatterBox dans la liste des utilisateurs qui est une référence à la UserControl connexe.

Dim user = "Codexer" 

Dim chatter = flpChat.Controls. 
      OfType(Of Chatter). 
      FirstOrDefault(Function(c) c.ChatName.StartsWith(user)) 
If chatter IsNot Nothing Then 
    chatter.Status = chatter.ChatStatus.Online 
End If 

Il est sous-optimal pour rechercher chaque fois et un Id serait mieux qu'un simple nom L'idéal . serait pour une classe ChatUser avec tous les autres choses l'application doit stocker par l'utilisateur la classe devrait inclure une référence au contrôle de sorte que lorsque les changements d'état ou autre, la classe pourrait simplement:

myChatterBox.Status = myStatus 

Résultat:

enter image description hereenter image description here

Certes, ils peuvent être créés avec considérablement moins de code. Au cours des choses, vous pouvez changer le statut de chaque image en définissant simplement la propriété associée. Comme un avantage supplémentaire, parce que vous n'êtes plus en train de créer des contrôles individuels, et parce que UserControl hérite de Component vous n'avez pas à vous soucier des fuites si/quand ceux-ci sont supprimés.

A lire:
Creating a Windows Form User Control

+1

Bonne réponse! :) –

+0

Nice :) cela fonctionne très bien et vous avez raison. moins de code est nécessaire. @Plutonix –

+0

Je suis toujours en train de lutter avec certaines choses @Plutonix. -AddHandler Lorsque je fais 'AddHandler C.Click, AddressOf Chatbox', je ne peux pas cliquer dessus. -Mise à jour Comment puis-je effectuer une mise à jour de ces contrôles lorsqu'ils sont effectués? Ces contrôles sont générés dynamiquement. –