但凡管理器之类的软件,存储数据是必不可少的。存储数据的话,有几种选择。一是用数据库,把数据存储到数据库里;一是用文本文件,把数据存储到文本文件里;一种是利用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()
就报了如下的错误

有谁能解决这个问题么?并能提供Direct2D的详细的开发资料么。
现在还同时在研究SharpDX,但也苦于缺少相关的资料和教程,有谁能提供么?