初识XML及简单工厂运用--网络电视精灵
网络电视精灵
任务描述
1. 解析XML文件中的数据
三个简单的xml文件;
<?xml version="1.0" encoding="utf-8" ?>
<TVChannele>
<Channel>
<channelType>TypeA</channelType>
<tvChannel>北京电视台</tvChannel>
<path>files/北京电视台.xml</path>
</Channel>
<Channel>
<channelType>TypeB</channelType>
<tvChannel>凤凰卫视</tvChannel>
<path>files/凤凰卫视.xml</path>
</Channel>
</TVChannele>
FullChannels
<?xml version="1.0" encoding="utf-8" ?>
<typeA version ="1.0">
<channelName>北京电视台</channelName><!--电视台-->
<tvProgramTable>
<tvProgram>
<playTime>-- :</playTime><!--节目播出时间-->
<meridien>早间档</meridien><!--时段-->
<programName>重播:国际双行线</programName><!--节目名称-->
<path>E:\</path><!--节目视频的本地路径-->
</tvProgram>
<tvProgram>
<playTime>-- :</playTime>
<!--节目播出时间-->
<meridien>早间档</meridien>
<!--时段-->
<programName>北京您早</programName>
<!--节目名称-->
<path>E:\</path>
<!--节目视频的本地路径-->
</tvProgram>
<tvProgram>
<playTime>-- :</playTime>
<!--节目播出时间-->
<meridien>早间档</meridien>
<!--时段-->
<programName>重播:《红星剧场》32集剧:勇者无敌</programName>
<!--节目名称-->
<path>E:\</path>
<!--节目视频的本地路径-->
</tvProgram>
</tvProgramTable>
</typeA>
北京电视台.xml
<?xml version="1.0" encoding="utf-8" ?>
<typeB version ="1.0">
<channelName>凤凰电视台</channelName>
<!--电视台-->
<tvProgramTable>
<tvProgram>
<playTime>-- :</playTime>
<!--节目播出时间-->
<meridien>早间档</meridien>
<!--时段-->
<programName>重播:国际双行线</programName>
<!--节目名称-->
<path>E:\</path>
<!--节目视频的本地路径-->
</tvProgram>
</tvProgramTable>
</typeB>
凤凰卫视.xml
2. 将”FullChannels.xml”文件中所有的频道添加到窗体的TreeView控件中.
3. 在TreeView控件中选取频道,将该频道的节目列表显示在窗体的DataGrideView控件中.
项目框架的搭建
分析网络精灵的大致结构,创建对应的类
1. 创建对应的类


ChannelFactory(简单工厂):通过简单工厂创建频道子类
public class ChannelFactory
{
//通过工厂创建频道子类
public static ChannelBase CreateChannel(string type)
{
ChannelBase channel = null;
switch (type)
{
case "TypeA":
channel=new TypeAChannel();
break;
case "TypeB":
channel = new TypeBChannel();
break;
default:
break;
}
return channel;
}
}
ChannelFactory
ChannelManager(频道管理类):解析” FullChannels.xml”文件,创建存储所有频道信息的集合,并将频道名添加到TreeView控件中
核心思路
1. 创建了道管理类,添加一个加载所有频道信息的方法(代码之后添加)LoadAllChannel()
当我们选取某一节点时实际获取到的是该节点Text值对应的频道对象.所以使用Dctionary<>来存储所有的频道对象
public ChannelManager()
{
fullChannels = new Dictionary<string, ChannelBase>();
}
//定义一个容器,承载所有的频道集合(Key:频道名称 Value:频道对象)
private Dictionary<string, ChannelBase> fullChannels ;
public Dictionary<string, ChannelBase> FullChannels
{
get { return fullChannels; }
set { fullChannels = value; }
}
fullChannels
2. 接下来就是给窗体中的TreeView控件中添加数据,分析:通过foreach将字典中的集合数据拆解,每一项对应的就是一个TreeNode对象,我们需要的是向”所有电视台”节点下添加电视台的名称属性.而名称属性对应的就是一个Channel对象,我们用Tag属性存储.
//01.写一个方法来解析xml,并且来给箱子中装数据
public void ParseXmlToDictionary()
{
XmlDocument doc=new XmlDocument();
doc.Load("files/Fullchannels.xml");
//获取根节点
XmlNode root=doc.DocumentElement;
foreach (XmlNode item in root.ChildNodes)
{ //一个item代表一个Channel节点
//获取类型
string type=item["channelType"].InnerText;
ChannelBase channel= ChannelFactory.CreateChannel(type);
//名称
channel.ChannelName = item["tvChannel"].InnerText;
channel.Path = item["path"].InnerText;
channel.Type = type; fullChannels.Add(channel.ChannelName,channel);
}
}
ParseXmlToDictionary
private void FrmMain_Load(object sender, EventArgs e)
{
//将ChannelManage类当中的容器FullChannels中的数据拎到TreeView上,
//根据思路,集合中每一项的Value值都是一个频道对应,没遍历到一个
//频道对象,我们就形成TV上的一个TreeNode
//01.加载根节点的方法
LoadRootNode();
//02.将集合中的数据拆解成是“所有电台下的”多个子节点
ChannelManager manager=new ChannelManager();
manager.ParseXmlToDictionary();
Dictionary<string,ChannelBase> dic=manager.FullChannels;
foreach (var channel in dic.Values)
{
//转化过程
TreeNode tn=new TreeNode();
tn.Text = channel.ChannelName;
tn.Tag = channel; //让tn加到所有电台下
allNode.Nodes.Add(tn);
}
}
节点对象的绑定
3. 将当前选中的电台的节目列表显示在dgv(DataGrideView)中显示出来,只需要将dgv的datasource属性设为当前选中电视台的节目列表list<Progeram>即可.
(我们在选取节点时应清楚一件事,在我们点击节点已获取到该电视台的节目列表,获取信息应该发生在我们点击节点的时候还是应该发生在选取之后)
private void tvChannel_AfterSelect(object sender, TreeViewEventArgs e)
{ //01.获取到用户选择的节点
TreeNode selectedNode = tvChannel.SelectedNode;
if (selectedNode.Level==&&selectedNode.Parent.Text=="所有电视台")
{
ChannelBase channel = (ChannelBase)selectedNode.Tag;
//清集合
if (channel.TvList!=null)
{
channel.TvList.Clear();
}
channel.Fetch();
List<TvProgram> proList = channel.TvList;
dgvProgList.DataSource = proList;
} }
tvChannel_AfterSelect
写到这里,如果运行一下程序,会报错误
.
我们仔细回想一下,我们在给TreeView控件添加节点的时候,给节点的TAG属性绑定了具体的频道对象.可是TreeView在窗体显示前,第一个节点会被默认选中

所以我们要对其进行优化,也就是当窗体在打开时,对默认选取的节点经行判断
if (selectedNode.Level==&&selectedNode.Parent.Text=="所有电视台")
默认选取节点判断
我们会发现当我们多次点击同一电视台,该电视台的节目信息会在dgv中进行多次添加,所以进行以下处理
//清集合
if (channel.TvList!=null)
{
channel.TvList.Clear();
}
清理节目列表
4. 节点右键菜单的添加,在TreeView控件中不同的节点对应了不同的右键菜单,当我们点击”我的电视台”下的字节点时,右键菜单只能为删除,而当我点击”所有电视台”下的子节点时,右键菜单为添加到”我的电视台”和”删除,如果我们使用多个ContextMenuStrip对不同节点经行绑定,会造成冗余,我们可不可以使用一个ContextMenuStrip绑定到多个节点并使其显示不同的菜单呢?答案是肯定的,我们需要用到ContextMenuStrip的一个属性:Visible.

我们要在选取节点后对选取到的节点经行判断,并选择显示该节点的右键菜单项
if (tvAllChannel.SelectedNode.Level == && tvAllChannel.SelectedNode.Parent.Text == "所有电视台")
{
ctxAddToMyChannels.Items[].Visible = false;
ctxAddToMyChannels.Items[].Visible = false;
}
else if (tvAllChannel.SelectedNode.Level == && tvAllChannel.SelectedNode.Parent.Text == "我的电视台")
{
ctxAddToMyChannels.Items[].Visible = false;
ctxAddToMyChannels.Items[].Visible = false;
ctxAddToMyChannels.Items[].Visible = false;
}
else if (tvAllChannel.SelectedNode.Text == "所有电视台")
{
ctxAddToMyChannels.Items[].Visible = false;
ctxAddToMyChannels.Items[].Visible = false;
ctxAddToMyChannels.Items[].Visible = false;
节点右键菜单项
到了这里,这个小项目可以说已经告一段落,之后学习过IO流会继续对该项目进行优化.或许我所做的并不完美,存在着许多代码的复用和冗余,也希望看过的各位进行提点,帮助我获取更多更优的解决方案.小子在此先行谢过了~~~
初识XML及简单工厂运用--网络电视精灵的更多相关文章
- 继承,多态,集合,面向对象,XML文件解析,TreeView动态加载综合练习----->网络电视精灵项目练习、分析
网络电视精灵 项目运行状态如图: 项目完成后的类: 首先,将程序分为二部分进行: 一:TreeView节点内容的设计及编写: 1.1遍写XML文件:管理(FullChannels.xml),A类电视台 ...
- 网络电视精灵~分析~~~~~~简单工厂模式,继承和多态,解析XML文档,视频项目
小总结: 所用技术: 01.C/S架构,数据存储在XML文件中 02.简单工厂模式 03.继承和多态 04.解析XML文档技术 05.深入剖析内存中数据的走向 06.TreeView控件的使用 核心: ...
- 单例模式、简单工厂模式、XML解析
单例模式: 什么是单例模式? 针对特定问题提出的特定解决方案 为什么使用设计模式? 让程序有更好的可扩展性 在哪里使用? 一般情况下,开发中真正使用设计模式的地方,JVM(虚拟机)底层机制模式 usi ...
- 设计模式之简单工厂模式Simple Factory(四创建型)
工厂模式简介. 工厂模式专门负责将大量有共同接口的类实例化 工厂模式可以动态决定将哪一个类实例化,不必事先知道每次要实例化哪一个类. 工厂模式有三种形态: 1.简单工厂模式Simple Factory ...
- Java设计模式(一) 简单工厂模式不简单
摘要:本文介绍了简单工厂模式的概念,优缺点,实现方式,以及结合Annotation和反射的改良方案(让简单工厂模式不简单).同时介绍了简单工厂模式(未)遵循的OOP原则.最后给出了简单工厂模式在JDB ...
- Java设计模式2:简单工厂模式
简单工厂模式 简单工厂模式是类的创建模式,又叫做静态工厂方法模式.简单工厂模式由一个工厂对象决定生产出哪一种产品类的实例. 为什么要使用简单工厂模式 原因很简单:解耦. A对象如果要调用B对象,最简单 ...
- 深入浅出设计模式——简单工厂模式(Simple Factory)
介绍简单工厂模式不能说是一个设计模式,说它是一种编程习惯可能更恰当些.因为它至少不是Gof23种设计模式之一.但它在实际的编程中经常被用到,而且思想也非常简单,可以说是工厂方法模式的一个引导,所以我想 ...
- Design Patterns (简单工厂模式)
文章很长很精彩,如是初学请耐心观看.(大神请绕道!) 简单工厂模式: 1.创建型模式 2.简单工厂模式概述 3.简单工厂模式的结构与实现 4.简单工厂模式的应用实例 5.创建对象与使用对象 6.简单工 ...
- java笔记--策略模式和简单工厂模式
策略模式: --如果朋友您想转载本文章请注明转载地址"http://www.cnblogs.com/XHJT/p/3884781.html "谢谢-- 为什么使用:策略模式主要用于 ...
随机推荐
- 【不积跬步,无以致千里】五个常用的Linux监控脚本代码
为大家提供五个常用Linux监控脚本(查看主机网卡流量.系统状况监控.监控主机的磁盘空间,当使用空间超过90%就通过发mail来发警告.监控CPU和内存的使用情况.全方位监控主机),有需要的朋友不妨看 ...
- C++ 过载,重写,隐藏
1.过载:在一个类中(也就是一个作用域),方法名相同,形参表不同的方法. 2.重写:父类方法使用virtual,子类方法和方法的方法名,形参表,返回类型相同,子类可以不使用virtual,但是建议使用 ...
- 实现微信文章页面 http://mp.weixin.qq.com/s?__biz=MjM5MDI3OTAwMg==&mid=200337417&idx=1&sn=5959ed1d722c7da66b
首先发了一篇文章,在微信后台.复制文章链接管理员 保存到数据库 $notice_list = $db->getAll(" SELECT `title`,`file_url`,`arti ...
- 兼容:判断 iframe 是否加载完成
判断 iframe 是否加载完成其实与 判断 JavaScript 文件是否加载完成 采用的方法很类似 var iframe = document.createElement("iframe ...
- 解决Windows2008Server上PLSQL登录时报ORA-12557
公司的Oracle服务端是安装在一台Linux服务器上,版本号为11.1.0.7.0.我们开发的系统部署在Windows 2008 Server(x64),因为偶尔需要调用Oracle数据库,所以最开 ...
- Ruby简介,附带示例程序
Ruby语言是日本人松本行弘于1993年器开始着手研发,经历2年时间,发布了Ruby语言的第一个版本:0.95版. Ruby是一种非常简介的解释性语言,一种纯粹的面向对象编程语言,甚至比Jav ...
- js之parentElement属性
<html> <head> </head> <body> <form name="a "> <table name ...
- python--字符工厂函数dict()
字符工厂函数str() class str(object): """ str(object='') -> str str(bytes_or_buffer[, enc ...
- JForum 2.19源码部署到eclipse
前两天在研究免费论坛,通过oschina和相关的文档查阅,最终选择了jforum,首先他是java写的,其次方便二次开发,而且有些论坛的源码都已经不在维护了,jforum最近几个月还是有更新的,但是从 ...
- 自定义控件(视图)1期笔记01:View 和 ViewGroup
1.View 和 ViewGroup 图解关系: 2. View 和 ViewGroup 关系和作用: (1) 关系: • 继承关系 • 组合关系 (2) 作用: • View的作用: 提供 ...