电影管理器之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 IsGetType(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()

就报了如下的错误

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

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

电影管理器之XML存储电影信息数据的更多相关文章

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

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

  2. 编程实战——电影管理器之界面UI及动画切换

    编程实战——电影管理器之界面UI及动画切换 在前文“编程实战——电影管理器之利用MediaInfo获取高清视频文件的相关信息”中提到电影管理器的目的是方便播放影片,在想看影片时不需要在茫茫的文件夹下找 ...

  3. 编程实战——电影管理器之利用MediaInfo获取高清视频文件的相关信息

    随着高速(20M)宽带.HTPC.大容量硬盘(3T)的普及,下载高清片并利用大屏幕观看也成为普通的事情. 随着下载影片的增多,管理就有了问题,有时在茫茫文件夹下找寻一个影片也是一件费时费力的事. 于是 ...

  4. 开源 自由 java CMS - FreeCMS2.0 举APP产生信息数据

    项目地址:http://www.freeteam.cn/ 生成信息数据 生成当前管理网站下同意移动APP訪问的栏目的信息页面. 从左側管理菜单点击生成信息数据进入. 您能够选择须要生成的栏目,然后点击 ...

  5. Java豆瓣电影爬虫——使用Word2Vec分析电影短评数据

    在上篇实现了电影详情和短评数据的抓取.到目前为止,已经抓了2000多部电影电视以及20000多的短评数据. 数据本身没有规律和价值,需要通过分析提炼成知识才有意义.抱着试试玩的想法,准备做一个有关情感 ...

  6. 虚拟化(五):vsphere高可用群集与容错(存储DRS是一种可用于将多个数据存储作为单个数据存储群集进行管理的功能)

    vsphere高级功能需要vcenter server和共享存储的支持才能实现.vsphere的高级功能有 vmotion.storage vmotion.vsphere HA.vsphere DRS ...

  7. 三十一.MySQL存储引擎 、 数据导入导出 管理表记录 匹配条件

    1.MySQL存储引擎的配置 查看服务支持的存储引擎 查看默认存储类型 更改表的存储引擎 设置数据库服务默认使用的存储引擎 1.1 查看存储引擎信息 mysql> SHOW ENGINES\G ...

  8. 使用 MongoDB 存储商品分类信息

    此文已由作者温正湖授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 这是一篇MongoDB官网上的一篇文章,分析了使用MongoDB存储商品分类信息相比其他数据库的优势,并讲述 ...

  9. 在HDInsight中从Hadoop的兼容BLOB存储查询大数据的分析

    在HDInsight中从Hadoop的兼容BLOB存储查询大数据的分析 低成本的Blob存储是一个强大的.通用的Hadoop兼容Azure存储解决方式无缝集成HDInsight.通过Hadoop分布式 ...

随机推荐

  1. 使用Visual Studio创建映像向导(Image Sprite)——Web Essential

    原版的:Creating Image Sprite in Visual Studio - Web Essential 译者注:有关图片精灵的信息请參阅http://baike.baidu.com/vi ...

  2. 赵雅智_Android编码规范

    凝视 导入mycodetemplates.xml统一凝视样式 须要加凝视的地方 类凝视(必加) 方法凝视(必加) 块凝视主要是数据结构和算法的描写叙述(必加) 类成员变量和常量凝视(选择性加入) 单行 ...

  3. 汽车之家购买价格PC真正的原因阿拉丁

        网行业风起云涌,先是6月3号汽车之家天价竞购百度PC阿拉丁.接着今天又有消息说易车拿下百度移动阿拉丁.易车拿下百度移动阿拉丁能够想象.但PC阿拉丁被向来不屑流量购买,以自主流量自居的汽车之家拿 ...

  4. 基础总结篇之五:BroadcastReceiver应用具体解释

    問渠那得清如許?為有源頭活水來.南宋.朱熹<觀書有感> 据说程序猿是最爱学习的群体,IT男都知道,这个行业日新月异,必须不断地学习新知识,不断地为自己注入新奇的血液,才干使自己跟上技术的步 ...

  5. 推荐几个靠谱的VPN

    最近开发scala程序使用sbt构建工程时,下载很慢,有些依赖只能通过VPN才能下载下来.在网上搜索了一大堆提供VPN服务的.有一大部分不提供试用,而且还必须得按年购买,看起来是像骗子. 在这里推荐几 ...

  6. OpenSUSE 13.2使用VPN(PPTP)

    新年开始,有时查询个资料或是下个软件包并不是那么愉快,决定使用付费VPN,他们使用的是用户名及密码的验证方式 在网上找到了一个教程,挺详尽的,如果想按照步骤能使用即可的原则,跟着我一起设置,想了解更多 ...

  7. JQuery -&gt; 超级简单的下拉菜单

    使用jquery实现一个超级简单的下拉菜单. 效果图 最初的效果 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvRmVlTGFuZw==/font/5a6L ...

  8. sql2005还原超长sql脚本,还原超大脚本文件

    原文:sql2005还原超长sql脚本,还原超大脚本文件 从外网把数据库用导出脚本的方式导出来了,280M的样子,导是导出来了,但是在本机执行sql脚本的时候,直接就是out of memory,之前 ...

  9. 删除指定表的所有索引,包括主键索引,唯一索引和普通索引 ,适用于sql server 2005,

    原文:删除指定表的所有索引,包括主键索引,唯一索引和普通索引 ,适用于sql server 2005, --删除指定表中所有索引 --用法:declare @tableName varchar(100 ...

  10. C++关于数字逆序输出的两种思路,及字符串逆序输出

    C++关于数字逆序输出的两种思路,及字符串逆序输出 作者:GREATCOFFEE 发布时间:NOVEMBER 15, 2012 分类:编程的艺术 最近在跟女神一起学C++(其实我是不怀好意),然后女神 ...