编程实战——电影管理器之XML存储电影信息数据-阿里云开发者社区

开发者社区> 万仓一黍> 正文

编程实战——电影管理器之XML存储电影信息数据

简介: 但凡管理器之类的软件,存储数据是必不可少的。存储数据的话,有几种选择。一是用数据库,把数据存储到数据库里;一是用文本文件,把数据存储到文本文件里;一种是利用XML文件,把数据对象转换为XML后,存储到XML文件(实际上也是文本文件)。
+关注继续查看

但凡管理器之类的软件,存储数据是必不可少的。存储数据的话,有几种选择。一是用数据库,把数据存储到数据库里;一是用文本文件,把数据存储到文本文件里;一种是利用XML文件,把数据对象转换为XML后,存储到XML文件(实际上也是文本文件)。

 

把数据对象和XML文件对应起来,有一个术语,称之为XML序列化。参看之前写的文章“利用XML序列化实现程序配置文件”,“简述Xml.Serialization如何序列化对象到XML文件

 

在本软件的设计中,设计了两种基本的数据对象

一是电影对象(类clsFilm),存储一部电影的信息,如:中文名(DesChineseName)、英文名(DesEnglishName)、时长(DesDuration)等

二是电影合集对象(类clsFilmCollection),存储多部电影合集的信息,如:中文名(DesChineseName)、文件个数(DesCount)、文件总大小(DesTotalSize)等。

 

在设计上,电影合集对象(类clsFilmCollection)包含子集合(ChildFilmItem),子集合(ChildFilmItem)中的元素可以是电影对象(类clsFilm)也可以是电影集合对象(类clsFilmCollection)。

例如:我现在有一个名为“欧美”的电影集合对象,子集合包含了名为“遗落战境”的电影对象和名为“变形金刚”的电影集合对象。而“变形金刚”的电影集合对象又包含了名为“变形金刚壹”、“变形金刚贰”、“变形金刚叁”的电影对象。

 

把这两种不同的类(类clsFilm和类clsFilmCollection)统一到集合(ChildFilmItem)中,采用的办法是让它们都实现I_Film接口(或者是定义一个抽象基类,两个类都去继承这个抽象基类)。如下面代码所示

 
Public Interface I_Film
    Property Title As String
    ReadOnly Property FilmImage As Image
    Property Des1 As String
    Property Des2 As String
    Property Des3 As String
    Property Des4 As String
    Function Hint() As List(Of I_Film)
    Function [GetType]() As Type
End Interface

Public Class clsFilm
    Implements I_Film

    Private _Des(3) As String
    Private _Title As String
    Private _ImageFile As String
    Private _Image As Image

    Private _FileName As String

    Public Sub New()
        _Image = Nothing
    End Sub

    Public Property FileName As String
        Set(value As String)
            _FileName = value
        End Set
        Get
            Return _FileName
        End Get
    End Property

    Public Property DesEnglishName As String Implements I_Film.Des1
        Get
            Return _Des(0)
        End Get
        Set(value As String)
            _Des(0) = value
        End Set
    End Property

    Public Property DesAudioLanguage As String Implements I_Film.Des2
        Get
            Return _Des(1)
        End Get
        Set(value As String)
            _Des(1) = value
        End Set
    End Property

    Public Property DesResolution As String Implements I_Film.Des3
        Get
            Return _Des(2)
        End Get
        Set(value As String)
            _Des(2) = value
        End Set
    End Property

    Public Property DesDuration As String Implements I_Film.Des4
        Get
            Return _Des(3)
        End Get
        Set(value As String)
            _Des(3) = value
        End Set
    End Property

    Public Property ImageFile As String
        Get
            Return _ImageFile
        End Get
        Set(value As String)
            _ImageFile = value
        End Set
    End Property

    Public ReadOnly Property FilmImage As System.Drawing.Image Implements I_Film.FilmImage
        Get
            If _Image Is Nothing Then
                _Image = Image.FromFile(_ImageFile).GetThumbnailImage(100, 140, Nothing, System.IntPtr.Zero)
            End If
            Return _Image
        End Get
    End Property

    Public Property DesChineseName As String Implements I_Film.Title
        Get
            Return _Title
        End Get
        Set(value As String)
            _Title = value
        End Set
    End Property

    Public Function Hint() As List(Of I_Film) Implements I_Film.Hint
        Return Nothing
    End Function

    Public Function GetType1() As System.Type Implements I_Film.GetType
        Return Me.GetType
    End Function
End Class

Public Class clsFilmCollection
    Implements I_Film

    Private _Title As String
    Private _Des(3) As String

    Private _ImageFile As String
    Private _Image As Image

    Public ChildFilmItem As List(Of I_Film)

    Public Sub New()
        ChildFilmItem = New List(Of I_Film)
    End Sub

    Public Property DesEnglishName As String Implements I_Film.Des1
        Get
            Return _Des(0)
        End Get
        Set(value As String)
            _Des(0) = value
        End Set
    End Property

    Public Property DesLanguage As String Implements I_Film.Des2
        Get
            Return _Des(1)
        End Get
        Set(value As String)
            _Des(1) = value
        End Set
    End Property

    Public Property DesCount As String Implements I_Film.Des3
        Get
            Return _Des(2)
        End Get
        Set(value As String)
            _Des(2) = value
        End Set
    End Property

    Public Property DesTotalSize As String Implements I_Film.Des4
        Get
            Return _Des(3)
        End Get
        Set(value As String)
            _Des(3) = value
        End Set
    End Property

    Public Property ImageFile As String
        Get
            Return _ImageFile
        End Get
        Set(value As String)
            _ImageFile = value
        End Set
    End Property

    Public ReadOnly Property FilmImage As System.Drawing.Image Implements I_Film.FilmImage
        Get
            If _Image Is Nothing Then
                _Image = Image.FromFile(_ImageFile).GetThumbnailImage(100, 140, Nothing, System.IntPtr.Zero)
            End If
            Return _Image
        End Get
    End Property

    Public Function Hint() As List(Of I_Film) Implements I_Film.Hint
        Return ChildFilmItem
    End Function

    Public Property DesChineseName As String Implements I_Film.Title
        Get
            Return _Title
        End Get
        Set(value As String)
            _Title = value
        End Set
    End Property

    Public Function GetType1() As System.Type Implements I_Film.GetType
        Return Me.GetType
    End Function
End Class

 

把这两个类(clsFilm和clsFilmCollection)实现相同的接口(I_Film),一是可以统一到一个集合中,另一个是在渲染到主画面的时候,只要针对接口I_Film编写代码即可。比方说,接口I_Film的Des4属性,在渲染的时候,只要把这个属性渲染到第四行即可。而相应的,类clsFilm对应的属性是DesDuration属性(时长),类clsFilmCollection对应的属性是DesTotalSize(总文件大小)。

 

还需要一个管理类,来管理它们,于是初步写了下面的类

 
Public Class clsFilmManager
    Private _Films As List(Of I_Film)

    Public Sub New()
        _Films = New List(Of I_Film)
    End Sub
End Class

 

接着用XmlSerializer类尝试把上面这个类序列化到XML文件。但是报错,没有序列化成功。在网上查了相关的资料后,有人说XmlSerializer类不支持序列化接口的集合,在把接口改成抽象类之后,就可以了。OK!!把接口改成抽象类试了试,还是不行(代码就不贴了)。

仔细想想,接口I_Film,有两个类clsFilm和clsFilmCollection实现它。在序列化的时候,XmlSerializer类可能无法明确的知道该接口对应是哪个类而导致序列化失败。

 

那就自己写一个XML的转换的类(clsFilmXml),实现数据对象和XML文件转换的功能。

先定义两个内部变量,_FileName和FilmCollections。FilmCollections是个clsFilmCollection集合。在我的设计里,程序启动的时候包含“欧美”、“动画”、“国内”、“港台”、“日韩”、“纪录”这六个电影合集。每个合集下再各自包含电影或电影合集

  
    Private _FileName As String
    Public FilmCollections As List(Of clsFilmCollection)

    Public Sub New()
        FilmCollections = New List(Of clsFilmCollection)
    End Sub

 

 

接下来是Load方法,把XML文件转换为电影数据对象。调用两个私有方法:_XML2Film方法,把XML文件中的FilmInfo标签转换为clsFilm对象;_XML2FilmCollection方法,把XML文件中的FilmCollection标签转换为clsFilmCollection对象。在_XML2FilmCollection方法中,还对子标签进行判断,如果是FilmInfo标签,则调用_XML2Film方法获得clsFilm对象;如果是FilmCollection标签,则再调用_XML2FilmCollection方法获得clsFilmCollection对象。

  
    Public Sub Load(XmlFile As String)
        _FileName = XmlFile

        Dim Document As New Xml.XmlDocument
        Document.Load(_FileName)

        Dim Films As Xml.XmlElement

        For Each Films In Document.DocumentElement.ChildNodes
            If Films.Name = "FilmCollection" Then FilmCollections.Add(_XML2FilmCollection(Films))
        Next
    End Sub 

    Private Function _XML2Film(Element As Xml.XmlElement) As clsFilm
        Dim Film As New clsFilm

        Dim ChildElement As Xml.XmlElement

        For Each ChildElement In Element.ChildNodes
            Select Case ChildElement.Name
                Case "FileName"
                    Film.FileName = ChildElement.InnerText
                Case "ImageFile"
                    Film.ImageFile = ChildElement.InnerText
                Case "DesChineseName"
                    Film.DesChineseName = ChildElement.InnerText
                Case "DesEnglishName"
                    Film.DesEnglishName = ChildElement.InnerText
                Case "DesDuration"
                    Film.DesDuration = ChildElement.InnerText
                Case "DesResolution"
                    Film.DesResolution = ChildElement.InnerText
                Case "DesAudioLanguage"
                    Film.DesAudioLanguage = ChildElement.InnerText
            End Select 
        Next

        Return Film
    End Function

    Private Function _XML2FilmCollection(Element As Xml.XmlElement) As clsFilmCollection
        Dim Films As New clsFilmCollection

        Dim ChildElement As Xml.XmlElement

        For Each ChildElement In Element.ChildNodes
            Select Case ChildElement.Name
                Case "ImageFile"
                    Films.ImageFile = ChildElement.InnerText
                Case "DesChineseName"
                    Films.DesChineseName = ChildElement.InnerText
                Case "DesEnglishName"
                    Films.DesEnglishName = ChildElement.InnerText
                Case "DesLanguage"
                    Films.DesLanguage = ChildElement.InnerText
                Case "DesCount"
                    Films.DesCount = ChildElement.InnerText
                Case "DesTotalSize"
                    Films.DesTotalSize = ChildElement.InnerText
                Case "FilmInfo"
                    Films.ChildFilmItem.Add(_XML2Film(ChildElement))
                Case "FilmCollection"
                    Films.ChildFilmItem.Add(_XML2FilmCollection(ChildElement))
            End Select
        Next
        Return Films
    End Function

 

 

接下来是Save方法,把电影数据对象转换为XML文件。和Load方法类似,也是调用了两个私有方法:_Film2XML方法,把clsFilm对象转换为FilmInfo标签;_FilmCollection2XML方法,把clsFilmCollection对象转换为FilmCollection标签。在_FilmCollection2XML方法中,对clsFilmCollection对象的ChildFilmItem集合中的元素进行判断(利用FilmItem.GetType Is GetType(clsFilm)语句进行判断),若是clsFilm对象,调用_Film2XML方法获得FilmInfo标签;若不是,再调用_FilmCollection2XML方法获得FilmCollection标签。

  
    Public Sub Save(Optional XmlFile As String = "")
        If XmlFile = "" Then XmlFile = _FileName

        Dim Document As New Xml.XmlDocument

        Dim Root As Xml.XmlElement = Document.CreateElement("FilmRoot")

        Dim Films As clsFilmCollection

        For Each Films In FilmCollections
            Root.AppendChild(_FilmCollection2XML(Films, Document))
        Next

        Document.AppendChild(Root)
        Document.Save(XmlFile)
    End Sub

    Private Function _Film2XML(Film As clsFilm, XML As Xml.XmlDocument) As Xml.XmlElement
        Dim FilmElement As Xml.XmlElement = XML.CreateElement("FilmInfo")

        FilmElement.InnerXml = String.Format("<FileName>{0}</FileName><ImageFile>{1}</ImageFile><DesChineseName>{2}</DesChineseName><DesEnglishName>{3}</DesEnglishName><DesDuration>{4}</DesDuration><DesResolution>{5}</DesResolution><DesAudioLanguage>{6}</DesAudioLanguage>", Film.FileName, Film.ImageFile, Film.DesChineseName, Film.DesEnglishName, Film.DesDuration, Film.DesResolution, Film.DesAudioLanguage)
        Return FilmElement
    End Function

    Private Function _FilmCollection2XML(Films As clsFilmCollection, Document As Xml.XmlDocument) As Xml.XmlElement
        Dim FilmCollectionElement As Xml.XmlElement = Document.CreateElement("FilmCollection")

        Dim S As String = ""
        With Films
            If .ImageFile <> "" Then S &= String.Format("<ImageFile>{0}</ImageFile>", .ImageFile)
            If .DesChineseName <> "" Then S &= String.Format("<DesChineseName>{0}</DesChineseName>", .DesChineseName)
            If .DesEnglishName <> "" Then S &= String.Format("<DesEnglishName>{0}</DesEnglishName>", .DesEnglishName)
            If .DesLanguage <> "" Then S &= String.Format("<DesLanguage>{0}</DesLanguage>", .DesLanguage)
            If .DesCount <> "" Then S &= String.Format("<DesCount>{0}</DesCount>", .DesCount)
            If .DesTotalSize <> "" Then S &= String.Format("<DesTotalSize>{0}</DesTotalSize>", .DesTotalSize)
        End With

        FilmCollectionElement.InnerXml = S

        Dim FilmItem As I_Film
        For Each FilmItem In Films.ChildFilmItem
            If FilmItem.GetType Is GetType(clsFilm) Then
                FilmCollectionElement.AppendChild(_Film2XML(FilmItem, Document))
            Else
                FilmCollectionElement.AppendChild(_FilmCollection2XML(FilmItem, Document))
            End If
        Next
        Return FilmCollectionElement
    End Function

 

 

为了后面的准备,我们有时需要获得所有的电影的中文名。于是,写了下面的两个方法。GetAllDesChineseName方法获得所有的电影的中文名,私有方法_GetAllDesChineseName获得指定clsFilmCollection对象下的所有的电影的中文名。还是利用FilmItem.GetType Is GetType(clsFilm)来判断是否是clsFilm对象,由于FilmItem是接口I_Film对象,那么如果FilmItem是clsFilm对象,则调用接口I_Film中的Des1属性(对应clsFilm对象的DesChineseName属性)来获得电影的中文名。

  
    Public Function GetAllDesChineseName() As List(Of String)
        Dim Films As clsFilmCollection
        Dim Names As New List(Of String)

        For Each Films In FilmCollections
            Names.AddRange(_GetAllDesChineseName(Films))
        Next
        Return Names
    End Function

    Private Function _GetAllDesChineseName(Films As clsFilmCollection) As List(Of String)
        Dim FilmItem As I_Film
        Dim Names As New List(Of String)

        For Each FilmItem In Films.ChildFilmItem
            If FilmItem.GetType Is GetType(clsFilm) Then
                Names.Add(FilmItem.Des1)
            Else
                Names.AddRange(_GetAllDesChineseName(FilmItem))
            End If
        Next

        Return Names
    End Function

最后是把电影添加到集合的方法。

有两个方法:

AddFilm方法,把clsFilm对象添加到由Films指定的集合中。例如AddFilm(Film , "欧美"),把Film添加到名为“欧美”的电影集合中

AddFilmByBrother方法,把clsFilm对象和BrotherFilm指定的电影组成一个集合

例如:原本已经有“变形金刚壹”这部电影,现在又有“变形金刚贰”这部电影,我当然希望这两部电影能在一个电影集合中,即“变形金刚”集合。

那么我可以调用AddFilmByBrother(Film , "变形金刚壹")来实现该功能。

首先要找到“变形金刚壹”电影的clsFilm对象,以及该对象所处的clsFilmCollection对象。通过私有方法_FindBrother来实现。

再判断该对象所处的clsFilmCollection对象是否是顶级集合(如“欧美”集合,通过判断clsFilmCollection对象的ImageFile属性)

如果是顶级集合,则新建一个clsFilmCollection对象,把这两部影片都添加到这个新建的clsFilmCollection对象(例如:把“变形金刚壹”和“变形金刚贰”都添加到新建的clsFilmCollection对象)。把BrotherFilm指定的电影从顶级集合中删掉。把新建的clsFilmCollection对象添加到顶级集合。

如果不是顶级集合(之前可能“变形金刚壹”和“变形金刚前传”组成了集合“变形金刚”),则把新电影添加到这个集合即可(把“变形金刚贰”添加到“变形金刚”集合)

 

最后_GetTotalSize方法是获得指定集合中所有的文件的大小,以GB为单位。

  
    Public Sub AddFilm(Film As clsFilm, Films As String)
        Dim FilmItem As clsFilmCollection

        For Each FilmItem In FilmCollections
            If FilmItem.DesChineseName = Films Then
                FilmItem.ChildFilmItem.Add(Film)
                Exit Sub
            End If
        Next
    End Sub

    Public Sub AddFilmByBrother(Film As clsFilm, BrotherFilm As String)

        Dim Films As clsFilmCollection, Brother As clsFilm = Nothing

        For Each Films In FilmCollections
            _FindBrother(BrotherFilm, Films, Brother)
            If Not (Brother Is Nothing) Then
                If Films.ImageFile = "" Then
                    Films.ChildFilmItem.Remove(Brother)
                    Dim NewFilms As New clsFilmCollection
                    NewFilms.DesChineseName = Brother.DesChineseName
                    NewFilms.DesEnglishName = Brother.DesEnglishName
                    NewFilms.DesLanguage = Brother.DesAudioLanguage
                    NewFilms.DesCount = 2
                    NewFilms.ImageFile = Brother.ImageFile
                    NewFilms.ChildFilmItem.Add(Brother)
                    NewFilms.ChildFilmItem.Add(Film)
                    NewFilms.DesTotalSize = _GetTotalSize(NewFilms)

                    Films.ChildFilmItem.Add(NewFilms)
                Else
                    Films.ChildFilmItem.Add(Film)
                    Films.DesCount = CInt(Films.DesCount) + 1
                    Films.DesTotalSize = _GetTotalSize(Films)
                End If
                Exit Sub
            End If
        Next

    End Sub

    Private Sub _FindBrother(BrotherFilm As String, ByRef Films As clsFilmCollection, ByRef Brother As clsFilm)
        Dim FilmItem As I_Film

        For Each FilmItem In Films.ChildFilmItem
            If FilmItem.GetType Is GetType(clsFilm) Then
                If FilmItem.Title = BrotherFilm Then
                    Brother = FilmItem
                    Exit Sub
                End If
            Else
                _FindBrother(BrotherFilm, FilmItem, Brother)
                If Not (Brother Is Nothing) Then
                    Films = FilmItem
                    Exit Sub
                End If
            End If
        Next
        Brother = Nothing
    End Sub

    Private Function _GetTotalSize(Films As clsFilmCollection) As String
        Dim SizeCount As Long = 0

        Dim FilmItem As clsFilm

        For Each FilmItem In Films.ChildFilmItem
            SizeCount += My.Computer.FileSystem.GetFileInfo(FilmItem.FileName).Length
        Next

        SizeCount = SizeCount * 10 / 1024 / 1024 / 1024

        Return CSng(SizeCount) / 10 & "GB" 

    End Function

 

 

 

最后是该类的完整代码(VB2010)

 
Public Class clsFilmXml
    Private _FileName As String
    Public FilmCollections As List(Of clsFilmCollection)

    Public Sub New()
        FilmCollections = New List(Of clsFilmCollection)
    End Sub

    Public Sub Load(XmlFile As String)
        _FileName = XmlFile

        Dim Document As New Xml.XmlDocument
        Document.Load(_FileName)

        Dim Films As Xml.XmlElement

        For Each Films In Document.DocumentElement.ChildNodes
            If Films.Name = "FilmCollection" Then FilmCollections.Add(_XML2FilmCollection(Films))
        Next
    End Sub

    Public Sub Save(Optional XmlFile As String = "")
        If XmlFile = "" Then XmlFile = _FileName

        Dim Document As New Xml.XmlDocument

        Dim Root As Xml.XmlElement = Document.CreateElement("FilmRoot")

        Dim Films As clsFilmCollection

        For Each Films In FilmCollections
            Root.AppendChild(_FilmCollection2XML(Films, Document))
        Next

        Document.AppendChild(Root)
        Document.Save(XmlFile)
    End Sub

    Private Function _Film2XML(Film As clsFilm, XML As Xml.XmlDocument) As Xml.XmlElement
        Dim FilmElement As Xml.XmlElement = XML.CreateElement("FilmInfo")

        FilmElement.InnerXml = String.Format("<FileName>{0}</FileName><ImageFile>{1}</ImageFile><DesChineseName>{2}</DesChineseName><DesEnglishName>{3}</DesEnglishName><DesDuration>{4}</DesDuration><DesResolution>{5}</DesResolution><DesAudioLanguage>{6}</DesAudioLanguage>", Film.FileName, Film.ImageFile, Film.DesChineseName, Film.DesEnglishName, Film.DesDuration, Film.DesResolution, Film.DesAudioLanguage)
        Return FilmElement
    End Function

    Private Function _FilmCollection2XML(Films As clsFilmCollection, Document As Xml.XmlDocument) As Xml.XmlElement
        Dim FilmCollectionElement As Xml.XmlElement = Document.CreateElement("FilmCollection")

        Dim S As String = ""
        With Films
            If .ImageFile <> "" Then S &= String.Format("<ImageFile>{0}</ImageFile>", .ImageFile)
            If .DesChineseName <> "" Then S &= String.Format("<DesChineseName>{0}</DesChineseName>", .DesChineseName)
            If .DesEnglishName <> "" Then S &= String.Format("<DesEnglishName>{0}</DesEnglishName>", .DesEnglishName)
            If .DesLanguage <> "" Then S &= String.Format("<DesLanguage>{0}</DesLanguage>", .DesLanguage)
            If .DesCount <> "" Then S &= String.Format("<DesCount>{0}</DesCount>", .DesCount)
            If .DesTotalSize <> "" Then S &= String.Format("<DesTotalSize>{0}</DesTotalSize>", .DesTotalSize)
        End With

        FilmCollectionElement.InnerXml = S

        Dim FilmItem As I_Film
        For Each FilmItem In Films.ChildFilmItem
            If FilmItem.GetType Is GetType(clsFilm) Then
                FilmCollectionElement.AppendChild(_Film2XML(FilmItem, Document))
            Else
                FilmCollectionElement.AppendChild(_FilmCollection2XML(FilmItem, Document))
            End If
        Next
        Return FilmCollectionElement
    End Function

    Private Function _XML2Film(Element As Xml.XmlElement) As clsFilm
        Dim Film As New clsFilm

        Dim ChildElement As Xml.XmlElement

        For Each ChildElement In Element.ChildNodes
            Select Case ChildElement.Name
                Case "FileName"
                    Film.FileName = ChildElement.InnerText
                Case "ImageFile"
                    Film.ImageFile = ChildElement.InnerText
                Case "DesChineseName"
                    Film.DesChineseName = ChildElement.InnerText
                Case "DesEnglishName"
                    Film.DesEnglishName = ChildElement.InnerText
                Case "DesDuration"
                    Film.DesDuration = ChildElement.InnerText
                Case "DesResolution"
                    Film.DesResolution = ChildElement.InnerText
                Case "DesAudioLanguage"
                    Film.DesAudioLanguage = ChildElement.InnerText
            End Select

        Next

        Return Film
    End Function

    Private Function _XML2FilmCollection(Element As Xml.XmlElement) As clsFilmCollection
        Dim Films As New clsFilmCollection

        Dim ChildElement As Xml.XmlElement

        For Each ChildElement In Element.ChildNodes
            Select Case ChildElement.Name
                Case "ImageFile"
                    Films.ImageFile = ChildElement.InnerText
                Case "DesChineseName"
                    Films.DesChineseName = ChildElement.InnerText
                Case "DesEnglishName"
                    Films.DesEnglishName = ChildElement.InnerText
                Case "DesLanguage"
                    Films.DesLanguage = ChildElement.InnerText
                Case "DesCount"
                    Films.DesCount = ChildElement.InnerText
                Case "DesTotalSize"
                    Films.DesTotalSize = ChildElement.InnerText
                Case "FilmInfo"
                    Films.ChildFilmItem.Add(_XML2Film(ChildElement))
                Case "FilmCollection"
                    Films.ChildFilmItem.Add(_XML2FilmCollection(ChildElement))
            End Select
        Next
        Return Films
    End Function

    Public Function GetAllDesChineseName() As List(Of String)
        Dim Films As clsFilmCollection
        Dim Names As New List(Of String)

        For Each Films In FilmCollections
            Names.AddRange(_GetAllDesChineseName(Films))
        Next
        Return Names
    End Function

    Private Function _GetAllDesChineseName(Films As clsFilmCollection) As List(Of String)
        Dim FilmItem As I_Film
        Dim Names As New List(Of String)

        For Each FilmItem In Films.ChildFilmItem
            If FilmItem.GetType Is GetType(clsFilm) Then
                Names.Add(FilmItem.Des1)
            Else
                Names.AddRange(_GetAllDesChineseName(FilmItem))
            End If
        Next

        Return Names
    End Function

    Public Sub AddFilm(Film As clsFilm, Films As String)
        Dim FilmItem As clsFilmCollection

        For Each FilmItem In FilmCollections
            If FilmItem.DesChineseName = Films Then
                FilmItem.ChildFilmItem.Add(Film)
                Exit Sub
            End If
        Next
    End Sub

    Public Sub AddFilmByBrother(Film As clsFilm, BrotherFilm As String)

        Dim Films As clsFilmCollection, Brother As clsFilm = Nothing

        For Each Films In FilmCollections
            _FindBrother(BrotherFilm, Films, Brother)
            If Not (Brother Is Nothing) Then
                If Films.ImageFile = "" Then
                    Films.ChildFilmItem.Remove(Brother)
                    Dim NewFilms As New clsFilmCollection
                    NewFilms.DesChineseName = Brother.DesChineseName
                    NewFilms.DesEnglishName = Brother.DesEnglishName
                    NewFilms.DesLanguage = Brother.DesAudioLanguage
                    NewFilms.DesCount = 2
                    NewFilms.ImageFile = Brother.ImageFile
                    NewFilms.ChildFilmItem.Add(Brother)
                    NewFilms.ChildFilmItem.Add(Film)
                    NewFilms.DesTotalSize = _GetTotalSize(NewFilms)

                    Films.ChildFilmItem.Add(NewFilms)
                Else
                    Films.ChildFilmItem.Add(Film)
                    Films.DesCount = CInt(Films.DesCount) + 1
                    Films.DesTotalSize = _GetTotalSize(Films)
                End If
                Exit Sub
            End If
        Next

    End Sub

    Private Sub _FindBrother(BrotherFilm As String, ByRef Films As clsFilmCollection, ByRef Brother As clsFilm)
        Dim FilmItem As I_Film

        For Each FilmItem In Films.ChildFilmItem
            If FilmItem.GetType Is GetType(clsFilm) Then
                If FilmItem.Title = BrotherFilm Then
                    Brother = FilmItem
                    Exit Sub
                End If
            Else
                _FindBrother(BrotherFilm, FilmItem, Brother)
                If Not (Brother Is Nothing) Then
                    Films = FilmItem
                    Exit Sub
                End If
            End If
        Next
        Brother = Nothing
    End Sub

    Private Function _GetTotalSize(Films As clsFilmCollection) As String
        Dim SizeCount As Long = 0

        Dim FilmItem As clsFilm

        For Each FilmItem In Films.ChildFilmItem
            SizeCount += My.Computer.FileSystem.GetFileInfo(FilmItem.FileName).Length
        Next

        SizeCount = SizeCount * 10 / 1024 / 1024 / 1024

        Return CSng(SizeCount) / 10 & "GB"


    End Function

End Class

 

贴代码于此,也是希望和大家交流,如果有什么建议的话,望不吝赐教。

 

 

题外话

在研究Direct2D时,从官网上下载了Windows API Code Pack 1.1后

解压到文件夹,在我的开发文档里引用了Microsoft.WindowsAPICodePack.DirectX.dll

在执行初始化语句时

_d2DFactory = Direct2D1.D2DFactory.CreateFactory()

就报了如下的错误

image

 

有谁能解决这个问题么?并能提供Direct2D的详细的开发资料么。

现在还同时在研究SharpDX,但也苦于缺少相关的资料和教程,有谁能提供么?

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
【转】]监听SMS消息/编程实现短信拦截
当设备接收到一条新的SMS消息时,就会广播一个包含了android.provider.Telephony.SMS_RECEIVED动作的Intent。注意,这个动作是一个字符串值,SDK 1.0不再包含对这个字符串的引用,因此,在你的应用程序中,你需要显式的指定它。
766 0
编程实战——电影管理器之界面UI及动画切换
在前文“编程实战——电影管理器之利用MediaInfo获取高清视频文件的相关信息”中提到电影管理器的目的是方便播放影片,在想看影片时不需要在茫茫的文件夹下找寻。   我对电影管理器的想法如下: 1、可以全键盘操作(不依赖鼠标),最好是利用键盘上的小数字键区就能完成全部操作。
839 0
PostgreSQL 10.1 手册_部分 III. 服务器管理_第 28 章 监控数据库活动_28.3. 查看锁
28.3. 查看锁 监控数据库活动的另外一个有用的工具是pg_locks系统表。这样就允许数据库管理员查看在锁管理器里面未解决的锁的信息。例如,这个功能可以被用于: 查看当前所有未解决的锁、在一个特定数据库中的关系上所有的锁、在一个特定关系上所有的锁,或者由一个特定PostgreSQL会话持有的所有的锁。
962 0
PostgreSQL 10.1 手册_部分 III. 服务器管理_第 28 章 监控数据库活动
第 28 章 监控数据库活动 目录 28.1. 标准 Unix 工具 28.2. 统计收集器 28.2.1. 统计收集配置 28.2.2. 查看统计信息 28.2.3. 统计函数 28.3. 查看锁 28.4. 进度报告 28.4.1. VACUUM进度报告 28.5. 动态追踪 28.5.1. 动态追踪的编译 28.5.2. 内建探针 28.5.3. 使用探针 28.5.4. 定义新探针 一个数据库管理员常常会疑惑,“系统现在正在做什么?”这一章会讨论如何搞清楚这个问题。
963 0
表格存储 SQL 操作实战
表格存储做为一款结构化存储系统,近期发布了新功能 SQL,大幅简化了查询的门槛,用户无需学习繁琐的 SDK,也不用区分表,索引等不同的接口,可以像访问传统的 MySQL 这类数据库一样,使用 SQL 的方式访问云原生的结构化大数据存储。下面我们就来具体实操下,看看查询用起来顺不顺手。
93 0
编程实战——电影管理器之XML存储电影信息数据
但凡管理器之类的软件,存储数据是必不可少的。存储数据的话,有几种选择。一是用数据库,把数据存储到数据库里;一是用文本文件,把数据存储到文本文件里;一种是利用XML文件,把数据对象转换为XML后,存储到XML文件(实际上也是文本文件)。
723 0
+关注
万仓一黍
算法研究
151
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载