继承,多态,集合,面向对象,XML文件解析,TreeView动态加载综合练习----->网络电视精灵项目练习、分析
网络电视精灵
项目运行状态如图:

项目完成后的类:
首先,将程序分为二部分进行:
一:TreeView节点内容的设计及编写:
1.1遍写XML文件:管理(FullChannels.xml),A类电视台北京电视台(北京电视台.xml),B类电视台凤凰卫视(凤凰卫视.xml)
1.2创建一个抽象的电视频道父类,ChannelBase,其中有成员:频道名称,频道路径,节目列表(以电视节目类作为类型的集合),解析频道节目单的抽象方法.代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 第八章_网络电视精灵
{
/// <summary>
/// 频道类
/// </summary>
public abstract class ChannelBase
{
//频道名称
public string ChannelName { get; set; }
//频道路径
public string Path { get; set; }
//节目列表
public List<TvProgram> ProgramList { get; set; } //电视节目类作为类型
//解析频道节目单信息
public abstract void Fetch();
}
}
1.3创建一个电视节目类,TvProgram类,该类主要负责定义节目的属性,为后续从xml文件中读取的内容提供存放位置
其中有成员:播出时间,时段,节目名称,节目文件路径.代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 第八章_网络电视精灵
{
public class TvProgram
{
//播出时间
public DateTime PlayTime { get; set; }
//时段
public string Median { get; set; }
//节目名称
public string ProgramName { get; set; }
//节目文件路径
public string FilePath { get; set; }
}
}
1.4电视台分为两类,那么有TypeAChannel,TypeAChannel两个继承自ChannelBase的子类:
A类电视(北京电视台):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
namespace 第八章_网络电视精灵
{
/// <summary>
/// A类电视台(北京电视台)
/// </summary>
public class TypeAChannel:ChannelBase
{
public override void Fetch()
{
//获取频道列表
XmlDocument doc = new XmlDocument();
//加载频道节目单文件
doc.Load("北京电视台.xml");
XmlElement root = doc.DocumentElement;
if (ProgramList == null)
{
ProgramList = new List<TvProgram>(); //给频道类的List集合中添加数据
}
foreach (XmlNode item in root.ChildNodes)
{
if (item.Name == "tvProgramTable")
{
foreach (XmlNode node in item.ChildNodes)
{
TvProgram program = new TvProgram();
program.PlayTime = DateTime.Parse(node["playTime"].InnerText);
program.Median = node["meridien"].InnerText;
program.ProgramName = node["programName"].InnerText;
program.FilePath = node["path"].InnerText;
ProgramList.Add(program);
}
}
}
}
}
}
B类电视(凤凰卫视)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
namespace 第八章_网络电视精灵
{
/// <summary>
/// B类电视(凤凰卫视)
/// </summary>
public class TypeBChannel:ChannelBase
{
public override void Fetch()
{
//获取频道列表
XmlDocument doc = new XmlDocument();
try
{
//加载频道节目单文件
doc.Load("凤凰卫视.xml");
}
catch (Exception)
{
throw;
}
XmlElement root = doc.DocumentElement;
if (ProgramList == null)
{
ProgramList = new List<TvProgram>();
}
foreach (XmlNode item in root.ChildNodes)
{
if (item.Name == "ProgramList")
{
foreach (XmlNode node in item.ChildNodes)
{
TvProgram program = new TvProgram();
program.PlayTime = DateTime.Parse(node["playTime"].InnerText);
program.ProgramName = node["name"].InnerText;
program.FilePath = node["path"].InnerText;
ProgramList.Add(program);
}
}
}
}
}
}
1.5创建一个电视频道管理类,实现多态:
首先在频道管理类ChannelManager中写一个加载所有频道方法LoadAllChannel;
该方法作用读取FullChannels.xml文件,并且将读取到的内容赋值给ChannelBase 对象。关键的问题就转化成了如何创建一个ChannelBase对象。我们都知道ChannelBase本身是一个抽象类,无法创建实例。由此,我们想到可以通过其子类
来创建对象。由于不同子类实例化需要多次new,我们单独写了一个方法CreateChannel(string type),来创建子类实例,但是该子类实例存储在父类变量中。赋值完成后,我们需要将频道对象添加到字典中。那么
LoadAllChannel方法结束后,字典中就有了XML文档中的数据。也就是我们实现了将本地硬盘上的xml文件中的数据读取到了内存中的一个字典集合中。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
namespace 第八章_网络电视精灵
{
/// <summary>
/// 电视频道管理类
/// </summary>
public class ChannelManager
{
//频道文件路径
private string channelPath = "FullChannels.xml";
//全部频道
private Dictionary<string, ChannelBase> fullChannel = new Dictionary<string, ChannelBase>();
public Dictionary<string, ChannelBase> FullChannel
{
get { return fullChannel; }
set { fullChannel = value; }
}
//读取FullChannels.xml加载所有频道列表
public void LoadChannel()
{
fullChannel.Clear();
XmlDocument doc = new XmlDocument();
doc.Load(channelPath);
XmlElement root = doc.DocumentElement;
foreach (XmlNode item in root.ChildNodes)
{
ChannelBase channel = CreateChannel(item["channelType"].InnerText);
channel.ChannelName = item["tvChannel"].InnerText;
channel.Path = item["path"].InnerText;
fullChannel.Add(channel.ChannelName, channel);
}
}
//根据频道类型创建对象
public 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;
}
}
}
到此,为TreeView节点对象的准备工作就做完了,下面开始为TreeView的节点进行对象绑定以及右侧DataGridView的数据绑定:
二:为TreeView的节点进行对象绑定以及右侧DataGridView的数据绑定、右键菜单:
2.1初始化根节点并为DataGridView绑定数据:
private void FrmMain_Load(object sender, EventArgs e)
{
UpdateTreeView();
}
//TreeView加载频道信息
public void UpdateTreeView()
{
//清空所有节点
tvList.Nodes.Clear();
//初始化根节点
TreeNode node = new TreeNode("我的电视台");
tvList.Nodes.Add(node);
node = new TreeNode("所有电视台");
tvList.Nodes.Add(node);
ChannelManager man=new ChannelManager();
man.LoadChannel();
foreach (ChannelBase item in man.FullChannel.Values)
{
//定义一个TreeView节点
TreeNode tn = new TreeNode();
tn.Text = item.ChannelName;
tn.Tag = item;
tvList.Nodes[1].Nodes.Add(tn);
}
}
2.2实现右键菜单的添加功能:
( 在这一步活生生卡了一个小时,还是比较笨~ )
获取选中的节点,根据Tag属性获取对应频道对象,然后将选定的频道加入到我的电视台中:
ChannelManager cm = new ChannelManager();
ChannelBase channel = null;
//加入我的电视台
private void 加入ToolStripMenuItem_Click(object sender, EventArgs e)
{
channel= (ChannelBase)tvList.SelectedNode.Tag;
cm.LoadChannel();
TreeNode node = new TreeNode();
node.Text = channel.ChannelName;
node.Tag = channel;
tvList.Nodes[0].Nodes.Add(node);
}
2.3实现右键菜单的删除功能:
private void 删除ToolStripMenuItem_Click(object sender, EventArgs e)
{
ChannelBase chan=null;
chan=(ChannelBase)tvList.SelectedNode.Tag;
cm.FullChannel.Remove(chan.ChannelName);
tvList.Nodes.Remove(tvList.SelectedNode);
}
2.4还需要根据鼠标点击的节点位置判断右键菜单的显示:
//判断右键菜单的内容
if (tvList.SelectedNode.Level == 0)
{
cmsMenu.Items[0].Visible = false;
cmsMenu.Items[1].Visible = false;
}
else if (tvList.SelectedNode.Parent.Text == "我的电视台")
{
cmsMenu.Items[0].Visible = false;
cmsMenu.Items[1].Visible = true;
}
else if (tvList.SelectedNode.Parent.Text == "所有电视台")
{
cmsMenu.Items[1].Visible = false;
cmsMenu.Items[0].Visible = true;
}
2.5根据点击的节点判断DataGridView的内容:
if (tvList.SelectedNode.Text=="北京电视台")
{
TypeAChannel ta = new TypeAChannel();
ta.Fetch();
dgvList.DataSource = ta.ProgramList;
}
else if (tvList.SelectedNode.Text == "凤凰卫视")
{
TypeBChannel tb = new TypeBChannel();
tb.Fetch();
dgvList.DataSource = tb.ProgramList;
}
else
{
List<TvProgram> list = new List<TvProgram>();
dgvList.DataSource = list;
}
继续努力!
END
本人原创,如有转载,请注明出处.
继承,多态,集合,面向对象,XML文件解析,TreeView动态加载综合练习----->网络电视精灵项目练习、分析的更多相关文章
- android sax解析xml 文件 动态加载标题
要解决一个问题 : 问题描述为 把标题动态的加载到 listView子布局中 我们首先通过 java程序写一个把标题写到xml文件的程序.这个程序会在以后讲解. 现在截图 已经写好的xm文件格式如下 ...
- mybatis源码解析之Configuration加载(五)
概述 前面几篇文章主要看了mybatis配置文件configuation.xml中<setting>,<environments>标签的加载,接下来看一下mapper标签的解析 ...
- Android应用安全之外部动态加载DEX文件风险
1. 外部动态加载DEX文件风险描述 Android 系统提供了一种类加载器DexClassLoader,其可以在运行时动态加载并解释执行包含在JAR或APK文件内的DEX文件.外部动态加载DEX文件 ...
- AngularJS进阶(三十九)基于项目实战解析ng启动加载过程
基于项目实战解析ng启动加载过程 前言 在AngularJS项目开发过程中,自己将遇到的问题进行了整理.回过头来总结一下angular的启动过程. 下面以实际项目为例进行简要讲解. 1.载入ng库 2 ...
- 通过正则表达式实现简单xml文件解析
这是我通过正则表达式实现的xml文件解析工具,有些XHTML文件中包含特殊符号,暂时还无法正常使用. 设计思路:常见的xml文件都是单根树结构,工具的目的是通过递归的方式将整个文档树装载进一个Node ...
- 八、Android学习第七天——XML文件解析方法(转)
(转自:http://wenku.baidu.com/view/af39b3164431b90d6c85c72f.html) 八.Android学习第七天——XML文件解析方法 XML文件:exten ...
- android基础知识13:AndroidManifest.xml文件解析
注:本文转载于:http://blog.csdn.net/xianming01/article/details/7526987 AndroidManifest.xml文件解析. 1.重要性 Andro ...
- Android之AndroidManifest.xml文件解析
转自:Android学习笔记之AndroidManifest.xml文件解析 一.关于AndroidManifest.xml AndroidManifest.xml 是每个android程序中必须的文 ...
- 9.XML文件解析
一.XML简介 XML(EXtensible Markup Language),可扩展标记语言 特点:XML与操作系统.编程语言的开发平台无关 实现不同系统之间的数据交换 作用:数据交互 配置应用程序 ...
随机推荐
- FileWriter字符输出流和FileReader字符输出流
//FileWriter public class FileWriterDemo { //字符流:适用于文本文件,以字符为单位进行操作,经常和缓冲流一起使用 /** * 字符流操作步骤: * 1. ...
- SignalR1
SignalR循序渐进(一) 前阵子把玩了一下SignalR,起初以为只是个real-time的web通讯组件.研究了几天后发现,这玩意简直屌炸天,它完全就是个.net的双向异步通讯框架,用它能做很多 ...
- Fitnesse集成TestLink
TestLink作为开源测试管理工具,可以进行测试工程.测试计划以及执行计划的管理,而且TestLink团队提供了XML-PRC的接口供第三方工具调用,接口支持程度也比较好. Fitnesse作为开源 ...
- [置顶] 纯手工打造漂亮的垂直时间轴,使用最简单的HTML+CSS+JQUERY完成100个版本更新记录的华丽转身!
前言 FineUI控件库发展至今已经有 5 个年头,目前论坛注册的QQ会员 5000 多人,捐赠用户 500 多人(捐赠用户转化率达到10%以上,在国内开源领域相信这是一个梦幻数字!也足以证明Fine ...
- Dynamics CRM不发布JS调试
本博客已迁移至 http://www.krely.cn/ 上个项目做了一年多,大多是在做JS的开发,由于开发人数比较多,着实被坑的不轻.因为JS修改完成之后必须要发布,对于我们动辄几千行的JS的调 ...
- HTTP压缩算法SDCH
程序设计中使用的那些共享方法或者技术 前段时间看了个paper是讲述谷歌浏览器使用的压缩方法SDCH,其实原理还是比较简单的. 看了论文后就想总结一下程序中使用的一些共享方法或者技术吧. 1.Goog ...
- 【ios开发】Block编程
1 什么是block iOS SDK 4.0开始,Apple引入了block这一特性.字面上说,block就是一个代码块,但是它的神奇之处在于在内联(inline)执行的时候(这和C++很像)还可以传 ...
- 用邻接表或vector实现存边以及具体如何调用[模板]
存边: 对于指针实现的邻接表: struct edge{ int from,next,to,w; }E[maxn]; int head[maxn],tot=0;//head初始化为-1: void a ...
- 基于SQLite日志记录工具--Log4W
最近压迫自己写点自己的东西,但是水平不高,槽点多,望各位请轻喷,嘿嘿! 以前用过一个Log4Net的东东,但是保存的是文本文件,不好过滤,而且用的不多,也不太熟悉,所以自己也当写一个练练手吧! ...
- Hive UDAF开发之同时计算最大值与最小值
卷首语 前一篇文章hive UDAF开发入门和运行过程详解(转)里面讲过UDAF的开发过程,其中说到如果要深入理解UDAF的执行,可以看看求平均值的UDF的源码 本人在看完源码后,也还是没能十分理解里 ...