.net – 从多个动态图片框中更改图像

我正在使用带有状态图像的VB.NET制作联系人列表.
我正在从MSsql加载这个列表但是当我重新加载列表时它会闪烁.

此列表是一个带有动态创建的图片框和标签的TableLayoutPanel.

我的问题是:

当您重新加载我的联系人而不是重新加载整个列表时,如何在动态图片框中更改我的图像.

我创建表的代码

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,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,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,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,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,12)
            newLabel.Dock = DockStyle.Fill
            newLabel.TextAlign = ContentAlignment.MiddleLeft
            newLabel.Visible = True
            ChatContactList.Controls.Add(newLabel)

        End If

    End If

End While

我的联系人名单的图片

UserControl有点像子表单.它是各种控件的容器,它们共同起作用或代表某个逻辑单元.在这种情况下,它将是一些用户状态(属性)的可视化表示.您可以将它们放在一个UC上,并封装大部分代码来管理它们,而不是创建和管理单个控件.

在Solution Explorer窗口中,右键单击,选择Add,然后选择UserControl.我添加一个TableLayoutPanel,2个PictureBoxes和一个Label(当然所有都有正确的名称).还有一个ImageList,可快速抓取您的图像:

仅此一项就可以替换许多代码行来创建新控件,然后一遍又一遍地设置相同的属性.要使它们充当逻辑对象,您可以添加抽象选择图像的细节等属性

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

(编辑)我不喜欢使用ImageList的结果.此版本从资源加载一系列图像.除了只加载一个GreenUser副本供所有用户使用外,它还允许您根据需要进行定制.例如,将backcolor更改为SystemColors.Window以匹配用户主题.如果您还使用标签而不是图片框,则可以使用Text属性“?”甚至指出新消息的数量.

我相信还有更多内容,我可以想到一些我希望它知道的事情(比如用未读消息的数量覆盖绿色气球).但这里的重点是封装,DRY和可重用代码的概念.

编译时,工具箱中会有一个新的Chatter控件.使用公开的属性在运行时添加一些:

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)

Id将是唯一标识每个聊天参与者的东西.该名称通常不够(SO已超过50 pages of people named “Steve”),您将需要一种方法来识别将控件链接用户. (另一种方法是,用户列表中的ChatterBox引用是对相关UserControl的引用:

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

每次搜索都是次优的,并且Id会比仅仅名称更好.理想情况是ChatUser类包含应用程序必须由用户存储的所有其他内容.该类应包含对控件的引用,以便在状态发生变化时或类似情况下,类可以简单地:

myChatterBox.Status = myStatus

结果:

当然,它们可以用相当少的代码创建.在这种情况下,您可以通过设置相关属性来更改任一图像的状态.

作为一个额外的好处,因为您不再创建单独的控件,并且因为UserControl继承自Component,所以如果/何时删除它们,您不必担心泄漏.

必读:
Creating a Windows Form User Control

相关文章

Format[$] ( expr [ , fmt ] ) format 返回变体型 format$ 强...
VB6或者ASP 格式化时间为 MM/dd/yyyy 格式,竟然没有好的办...
在项目中添加如下代码:新建窗口来显示异常信息。 Namespace...
转了这一篇文章,原来一直想用C#做k3的插件开发,vb没有C#用...
Sub 分列() ‘以空格为分隔符,连续空格只算1个。对所选...
  窗体代码 1 Private Sub Text1_OLEDragDrop(Data As Dat...