zoukankan      html  css  js  c++  java
  • 初识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>2013-9-29 06:02</playTime><!--节目播出时间-->
          <meridien>早间档</meridien><!--时段-->
          <programName>重播:国际双行线</programName><!--节目名称-->
          <path>E:</path><!--节目视频的本地路径-->
        </tvProgram>
        <tvProgram>
          <playTime>2013-9-29 07:00</playTime>
          <!--节目播出时间-->
          <meridien>早间档</meridien>
          <!--时段-->
          <programName>北京您早</programName>
          <!--节目名称-->
          <path>E:</path>
          <!--节目视频的本地路径-->
        </tvProgram>
        <tvProgram>
          <playTime>2013-9-29 09:02</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>2013-9-29 01:30</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==1&&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==1&&selectedNode.Parent.Text=="所有电视台")
    默认选取节点判断

     

     

    我们会发现当我们多次点击同一电视台,该电视台的节目信息会在dgv中进行多次添加,所以进行以下处理

     //清集合
                    if (channel.TvList!=null)
                    {
                        channel.TvList.Clear();
                    }
    清理节目列表

    4. 节点右键菜单的添加,在TreeView控件中不同的节点对应了不同的右键菜单,当我们点击”我的电视台”下的字节点时,右键菜单只能为删除,而当我点击”所有电视台”下的子节点时,右键菜单为添加到”我的电视台”和”删除,如果我们使用多个ContextMenuStrip对不同节点经行绑定,会造成冗余,我们可不可以使用一个ContextMenuStrip绑定到多个节点并使其显示不同的菜单呢?答案是肯定的,我们需要用到ContextMenuStrip的一个属性:Visible.

     

    我们要在选取节点后对选取到的节点经行判断,并选择显示该节点的右键菜单项

                if (tvAllChannel.SelectedNode.Level == 1 && tvAllChannel.SelectedNode.Parent.Text == "所有电视台")
                {
                    ctxAddToMyChannels.Items[2].Visible = false;
                    ctxAddToMyChannels.Items[3].Visible = false;
                }
                else if (tvAllChannel.SelectedNode.Level == 1 && tvAllChannel.SelectedNode.Parent.Text == "我的电视台")
                {
                    ctxAddToMyChannels.Items[0].Visible = false;
                    ctxAddToMyChannels.Items[1].Visible = false;
                    ctxAddToMyChannels.Items[2].Visible = false;
                }
                else if (tvAllChannel.SelectedNode.Text == "所有电视台")
                {
                    ctxAddToMyChannels.Items[0].Visible = false;
                    ctxAddToMyChannels.Items[1].Visible = false;
                    ctxAddToMyChannels.Items[3].Visible = false;
    节点右键菜单项

    到了这里,这个小项目可以说已经告一段落,之后学习过IO流会继续对该项目进行优化.或许我所做的并不完美,存在着许多代码的复用和冗余,也希望看过的各位进行提点,帮助我获取更多更优的解决方案.小子在此先行谢过了~~~

  • 相关阅读:
    NSAttributedString可以强制转换为NSMutableAttributedString类型吗?下面这代码有什么问题 为什么报错
    jQuery中.bind() .live() .delegate() .on()的区别 和 三种方式写光棒事件 动画
    锋利的jQuery中的事件与动画
    使用jQuery快速高效制作网页交互特效
    Java中abstract和interface的区别
    一期结业KTV项目难点
    类和对象
    循环结构进阶
    Java中的数组
    Java初始化
  • 原文地址:https://www.cnblogs.com/Serean/p/4649286.html
Copyright © 2011-2022 走看看