//主窗体
//主代码
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace TVXmlRead { public partial class MainForm : Form { /// <summary> /// 管理器类 /// </summary> private ChannelManager myManager = new ChannelManager(); public MainForm() { InitializeComponent(); } /// <summary> /// 电视台初始化 /// </summary> private void InitChannel() { //加载所有频道信息 myManager.LoadChannel(); //加载用户定制的频道信息 myManager.LoadFromText(); //刷新TreeView显示 UpdateTreeView(); } /// <summary> /// 窗体加载事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void MainForm_Load(object sender, EventArgs e) { this.SetVisible(true); this.InitChannel(); } /// <summary> /// 控制DataGridView和listView的显示 /// </summary> /// <param name="boolInfo"></param> private void SetVisible(bool boolInfo) { this.dgvProgList.Visible = boolInfo; } /// <summary> /// 刷新频道列表 /// </summary> private void UpdateTreeView() { //清空所有节点 this.tvChannel.Nodes.Clear(); //初始化根结点 TreeNode nodeFirstLevel = new TreeNode("我的电视台"); nodeFirstLevel.ImageIndex = 0; this.tvChannel.Nodes.Add(nodeFirstLevel); nodeFirstLevel = new TreeNode("所有电视台"); this.tvChannel.Nodes.Add(nodeFirstLevel); //加载“所有电视台” foreach (ChannelBase dicOne in myManager.FullChannel.Values) { TreeNode node = new TreeNode(); node.Text = dicOne.ChannelName; node.Tag = dicOne; node.ImageIndex = 1; this.tvChannel.Nodes[1].Nodes.Add(node); } //加载“我的电视台” foreach (ChannelBase dicOne in myManager.Seria.MyFavor) { TreeNode node = new TreeNode(); node.Text = dicOne.ChannelName; node.Tag = dicOne; node.ImageIndex = 1; this.tvChannel.Nodes[0].Nodes.Add(node); } //展开所有节点 tvChannel.ExpandAll(); } /// <summary> /// 将一个电台添加到我的电台中 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void tsmAddToFavor_Click(object sender, EventArgs e) { TreeNode node = this.tvChannel.SelectedNode; //没有选中任何节点,返回 if (node == null) { return; } ChannelBase ch = (ChannelBase)node.Tag; //保证不重复 foreach (TreeNode nodeItem in this.tvChannel.Nodes[0].Nodes) { if (nodeItem.Text.Trim() == node.Text.Trim()) { return;//发现“我的收藏夹”中有这个电台,就退出,不再执行添加工作。 } } this.myManager.Seria.MyFavor.Add(ch); this.UpdateTreeView(); } /// <summary> /// 右键单击树型菜单,控制右键菜单的菜单项的显示: /// 即“所有电视台”的子节点的右键中只显示“加入到我的电台” /// 而“我的电视台”的子节点的右键只能显示"删除" /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void tvChannel_MouseClick(object sender, MouseEventArgs e) { //只处理右键事件 TreeNode node = this.tvChannel.SelectedNode; if (node != null && node.Level != 0)//有节点被选中且不是顶级节点 { //这句代码保证右键点击树的时候,那个节点处于选中状态 if (node.Parent.Text == "所有电视台") { //使"加入到我的电台"这个菜单项可见 cmenuRight.Items[1].Visible = false; cmenuRight.Items[0].Visible = true; } else { //使“删除”菜单项可见 cmenuRight.Items[0].Visible = false; cmenuRight.Items[1].Visible = true; } } else { cmenuRight.Items[1].Visible = false; cmenuRight.Items[0].Visible = false; } } private void TMenuItemDel_Click(object sender, EventArgs e) { TreeNode node = this.tvChannel.SelectedNode; //没有选中任何节点,返回 if (node == null) { return; } ChannelBase ch = (ChannelBase)node.Tag; this.myManager.Seria.MyFavor.Remove(ch); this.UpdateTreeView(); } /// <summary> /// 树形菜单选项改变事件:改变频道,加载选中频道的节目信息 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void tvChannel_AfterSelect(object sender, TreeViewEventArgs e) { //控制DataGridView的显示 this.SetVisible(true); //e.Node选中的节点 if (e.Node.Level != 0) { ChannelBase ch = (ChannelBase)e.Node.Tag; if (ch.ProgramList != null) { ch.ProgramList.Clear();//清除当前节目单 } ch.Fetch(); //读取节目单 this.dgvProgList.DataSource = ch.ProgramList; //绑定到数据展示控件显示 this.dgvProgList.Tag = ch.ChannelName; //将当前Dgv的Tag属性设为频道的名称 } } //退出应用程序 private void MainForm_FormClosed(object sender, FormClosedEventArgs e) { //退出之前存储信息 myManager.SaveAsTxt(); Application.Exit(); } } }
//ChannelBase.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Xml; namespace TVXmlRead { public abstract class ChannelBase { #region 属性 /// <summary> /// 频道名称 /// </summary> private string channelName; public string ChannelName { get { return channelName; } set { channelName = value; } } /// <summary> /// 频道路径 /// </summary> private string path; public string Path { get { return path; } set { path = value; } } /// <summary> /// 节目列表 /// </summary> private List<TvProgram> programList; public List< TvProgram> ProgramList { get { return programList; } set { this.programList = value; } } #endregion public abstract void Fetch(); } }
//ChannelManager.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Xml; using System.IO; using System.Windows.Forms; namespace TVXmlRead { public class ChannelManager { /// <summary> /// 频道文件路径 /// </summary> private string channelPath ="files/FullChannels.xml"; /// <summary> /// 全部频道 /// </summary> private Dictionary<string, ChannelBase> fullChannel=new Dictionary<string,ChannelBase>(); public Dictionary<string, ChannelBase> FullChannel { get { return fullChannel; } } //持久化信息 private SavingInfo seria = new SavingInfo(); public SavingInfo Seria { get { return seria; } } /// <summary> /// 启动程序时,读取FullChannels.xml,加载所有频道列表 /// </summary> public void LoadChannel() { //预处理集合,防止被重复加载数据 try { fullChannel.Clear(); XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(channelPath); XmlElement xmlRoot = xmlDoc.DocumentElement; foreach (XmlNode node in xmlRoot.ChildNodes) { //根据频道类型创建对象 ChannelBase channel =CreateChannel(node["channelType"].InnerText); channel.ChannelName = node["tvChannel"].InnerText; channel.Path = node["path"].InnerText; this.fullChannel.Add(channel.ChannelName, channel); } } catch { throw new Exception("数据加载错误!"); } } 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; } //保存定制频道信息的文本文件名称 private string saveFileName = @"files\save"; /// <summary> /// 将我的电台信息存储到文本文件之中 /// 要解决中文乱码问题 /// </summary> public void SaveAsTxt() { try { FileStream fs = new FileStream(saveFileName + ".txt", FileMode.Create); StreamWriter writer = new StreamWriter(fs, Encoding.GetEncoding("GB2312")); string type = ""; for (int index = 0; index < this.seria.MyFavor.Count; index++) { ChannelBase channel = this.seria.MyFavor[index]; if (channel is TypeBChannel) { type = "TypeB"; } else { type = "TypeA"; } writer.WriteLine(type + "|" + channel.ChannelName + "|" + channel.Path); } writer.WriteLine("End of my Favor"); writer.Close(); fs.Close(); } catch (Exception ex) { MessageBox.Show("写入文件失败:" + ex.ToString()); } } /// <summary> /// 从文本文件之中读取"我的电台"信息 /// </summary> public void LoadFromText() { //#region 存在性判断 if (!File.Exists(@"files\save.txt")) {//不存在则不再处理 return; } //#endregion try { StreamReader reader = new StreamReader(saveFileName + ".txt", Encoding.GetEncoding("GB2312")); string line = reader.ReadLine(); string[] propertyValues; ChannelBase channel = null; while (line.Trim() != "End of my Favor") { propertyValues = line.Split('|'); channel = CreateChannel(propertyValues[0]); channel.ChannelName = propertyValues[1]; channel.Path = propertyValues[2]; this.seria.MyFavor.Add(channel); line = reader.ReadLine(); } reader.Close(); } catch (Exception ex) { MessageBox.Show("文件操作异常:" + ex.Message); } } } }