小總結:
所用技術:
01.C/S架構,數據存儲在XML文件中
02.簡單工廠模式
03.繼承和多態
04.解析XML文檔技術
05.深入剖析內存中數據的走向
06.TreeView控件的使用
核心:通過該項目,我們對業務流程有一個整體把控。對繼承和多態有深入的了解
下面是類圖:
主界面圖:
核心思路:
1 1.首先在頻道管理類ChannelManager中寫一個加載所有頻道方法LoadAllChannel; 2 3 該方法作用讀取FullChannels.xml文件,並且將讀取到的內容賦值給ChannelBase 對象。關鍵的問題就轉化成了如何創建一個ChannelBase對象。我們都知道ChannelBase本身是一個抽象類,無法創建實例。由此,我們想到可以通過其子類來創建對象。由於不同子類實例化需要多次new,我們單獨寫了一個工廠類(ChannelFafactory),來創建子類實例,但是該子類實例存儲在父類變量中。賦值完成后,我們需要將頻道對象添加到字典中。那么 4 5 LoadAllChannel方法結束后,字典中就有了XML文檔中的數據。也就是我們實現了將 6 7 本地硬盤上的xml文件中的數據讀取到了內存中的一個字典集合中。

9 10 2.將集合中的數據綁定到TreeView中 11 將字典集合中的數據通過Foreach拆解,每循環一項,都創建一個TreeNode對象。 12 並且將集合中的屬性賦值給節點對應的屬性。然后將拼接處的節點添加到TreeView上 13 。這里需要注意的是,如何找到TreeView控件中的【所有電視台】這個節點,因為 14 我們需要在該節點上添加頻道名稱。代碼如下:

1 在對應的頻道子類中書寫Fetch方法,解析對應的頻道xml文件,然后將xml文件中的數據讀取到 public List<TvProgram> TvList { get; set; }中。 2 2.將TvList中的數據綁定到DataGridView上 3 4 實現TreeView的右鍵菜單功能(能添加電台和刪除電台) 5 核心思路: 6 1.添加電台
1 其實我們在做的事情就是先獲取所有電台的某一個電台(北京電視台),然后通過 2 Tag屬性拿到該電台對應的屬性,將拆解出來的屬性賦值給我的電台下的某一個 3 節點,由於節點不存在,所以我們要構造出一個節點。然后賦值,賦值完成后,我們就將構造出來的 節點添加到我的電台下就OK。 4 5 當然,上面的操作僅僅是界面上新增電台的一個假象。程序再次運行時,我們添加的電台並沒有保存。所以我們要將選中的電台添加到我的電台(由於我喜歡的電台可能有多個,所以我們定義了一個集合。)集合中。因為我們大家都知道集合中的數據時存儲在內存中的,所以我們要向程序下次運行時,顯示出我們添加的電台,那么就必須將集合中的數據永久保存。當然我們知道,永久保存數據的方法有很多,在這里我們采取的是使用txt文件的方式,所以我們書寫了一個方法來幫我們完成這項工作,sw.WriteLine(“End”)主要為了方便后面對文本文件的讀取
通過Visible屬性控制右鍵菜單的顯示和隱藏:
1 網絡電視精靈后續思路 2 1.點擊TreeView上某個電視台節點后,顯示該頻道下所有的節目單, 3 將節目單內容填充到DataGridView控件中。 4 思路分析:既然TypeAChannel:ChannelBase對應的北京電視台,那么我們需要找到保存 5 北京電視台中所有節目的xml文件,然后接續該xml文件,每一個<TvProgram> 6 節點都是一個節目單對象。我只需要將解析出的內容加載到集合中。集合中就存儲了 7 一系列TvProgram對象,我只需要將該集合綁定到DataGridView上就OK了。 8 9 DgvList.DataSource=list;
下面是本人寫的一些代碼:
:
1 ChannelManager manager = new ChannelManager(); 2 private void Form1_Load(object sender, EventArgs e) 3 { 4 lvTV.Visible = false;//讓ListView控件隱藏 5 dgvProgList.AutoGenerateColumns = false;//不自動產生英文列 6 //1.加載我的電視台和所有電視台(TvChannel中的固定項) 7 TreeNode myNode = new TreeNode(); 8 //點擊該節點時,對應的圖片改變 9 myNode.SelectedImageIndex = 1; 10 myNode.Text = "我的電視台"; 11 12 TreeNode allNode = new TreeNode(); 13 allNode.SelectedImageIndex = 1; 14 allNode.Text = "所有電視台"; 15 16 //讓節點和TreeView產生關系 17 tvChannel.Nodes.Add(myNode); 18 tvChannel.Nodes.Add(allNode); 19 20 //2.接下來我們需要讀取 xml文件 獲取所有電視台下的子節點 21 //遍歷集合中的每一項,然后拼接成一個TreeNode即可 22 23 manager.LoadAllChannel(); 24 Dictionary<string, ChannelBase> fullChannel = manager.FullChannel; 25 foreach (ChannelBase channelBase in fullChannel.Values) 26 { 27 //每遍歷一次,都是一個頻道,每一次都要創建一個TreeNode節點 28 TreeNode tn = new TreeNode(); 29 tn.Text = channelBase.ChannelName; 30 //Tag 31 tn.Tag = channelBase; 32 33 //找到所有電台節點,在所有電台的基礎上增加子節點 34 tvChannel.Nodes[1].Nodes.Add(tn); 35 } 36 37 38 39 //從txt文檔將數據讀取到集合中 40 if (File.Exists("files/Save.txt")) 41 { 42 manager.LoadFromTxt(); 43 foreach (ChannelBase item in manager.MyChannelList.ChannelList) 44 { 45 //每一項item都是一個TreeNode對象 46 TreeNode tn=new TreeNode(); 47 tn.Text = item.ChannelName; 48 tn.Tag = item; 49 50 myNode.Nodes.Add(tn); 51 } 52 } 53 54 imageIcons.Images[0].Save("01.jpg"); 55 imageIcons.Images[1].Save("02.jpg"); 56 57 //02.遍歷集合拼接節點 58 59 } 60 61 //選中TreeView中國某個節點后執行的事件 62 private void tvChannel_AfterSelect(object sender, TreeViewEventArgs e) 63 { 64 TreeNode tn = tvChannel.SelectedNode;//獲取當前選中的節點對象 65 //點擊某個節點(必須是子節點:Level==1) 66 if (tn!=null&&tn.Level==1) 67 { 68 //發現是子節點,才獲取到頻道對象 69 ChannelBase channel = (ChannelBase) tn.Tag; 70 if (channel.TvList!=null) 71 { 72 channel.TvList.Clear(); 73 } 74 channel.Fetch(); 75 76 //然后將tvList集合綁定到DGV上 77 dgvProgList.DataSource = channel.TvList; 78 } 79 80 } 81 // 82 private void tvChannel_MouseClick(object sender, MouseEventArgs e) 83 { 84 TreeNode node = tvChannel.SelectedNode; 85 if (node!=null&&node.Level==1)//選中了電視台節點 86 { 87 if (node.Parent.Text=="我的電視台") 88 { 89 cmenuRight.Items[0].Visible = false; 90 cmenuRight.Items[1].Visible = true; 91 } 92 else 93 { 94 cmenuRight.Items[0].Visible = true; 95 cmenuRight.Items[1].Visible = false; 96 } 97 } 98 else 99 { 100 //如果選中節點為父節點,那么添加、刪除菜單項都不顯示 101 cmenuRight.Items[0].Visible = false; 102 cmenuRight.Items[1].Visible = false; 103 } 104 105 } 106 //加入我的電台 107 private void tsmAddToFavor_Click(object sender, EventArgs e) 108 { 109 //如何將電台從所有電台加載到我的電台 110 //01.獲取選中項 111 TreeNode tn = tvChannel.SelectedNode; 112 if (tn==null) 113 { 114 return; 115 } 116 //02.判斷我的電台下是否已經存在你要加入的電台 117 foreach (TreeNode child in tvChannel.Nodes[0].Nodes) 118 { 119 if (child.Text==tn.Text) 120 { 121 return; 122 } 123 } 124 //03.真正加入節點到我的電台下 125 //把當前選中的節點的Tag屬性取出來,轉換成ChannelBase 126 ChannelBase channel=(ChannelBase) tn.Tag; 127 //04.將channel對象添加到我的電台下成為我的電台的一個節點 128 TreeNode node=new TreeNode(); 129 node.Text = channel.ChannelName; 130 node.Tag = channel; 131 tvChannel.Nodes[0].Nodes.Add(node); 132 //04.將channel加入到集合中 133 manager.MyChannelList.ChannelList.Add(channel); 134 //05.如果集合在main 中,那么將集合中數據寫入文本文件的時候比較麻煩 135 //所以我們將集合和SaveToTxt方法都寫入了ChannelManager類 136 manager.SaveToTxt(); 137 } 138 139 //從我的電台中刪除 140 private void TMenuItemDel_Click(object sender, EventArgs e) 141 { 142 //01.先獲取我的電台下要刪除的電台 143 //02.從Tv上移除 144 //03.從集合中移除 145 //04.SaveToTxt() 146 147 }148 //播放視頻 149 private void tsmPlay_Click(object sender, EventArgs e) 150 { 151 string path= dgvProgList.SelectedRows[0].Cells[3].Value.ToString(); 152 FrmPlay frm=new FrmPlay(); 153 frm.mypath = path; 154 frm.Show(); 155 frm.Play(); 156 }
父類:
1 /// <summary> 2 /// 頻道基類 3 /// </summary> 4 public abstract class ChannelBase 5 { 6 //頻道名稱 7 public string ChannelName { get; set; } 8 //頻道路徑 9 public string Path { get; set; } 10 //頻道類型 11 public string Type { get; set; } 12 //節目列表,該頻道上的所有節目列表 13 public List<TvProgram> TvList { get; set; } 14 //獲取頻道列表:通過Fetch方法獲取該頻道擁有的所有節目列表 15 public abstract void Fetch(); 16 17 }
A頻道
1 //解析北京電視台中所有的節目單集合 2 public override void Fetch() 3 { 4 //既然我們已經拿到了所有的頻道,只需要加載對應頻道下節目就OK 5 //將硬盤中xml文件的數據讀取到了泛型集合中(內存中) 6 XmlDocument doc=new XmlDocument(); 7 doc.Load(Path); 8 if (TvList==null) 9 { 10 TvList=new List<TvProgram>(); 11 } 12 XmlElement root = doc.DocumentElement; 13 foreach (XmlNode item in root.ChildNodes) 14 { 15 if (item.Name == "tvProgramTable") 16 { 17 // 18 foreach (XmlNode tn in item.ChildNodes) 19 { 20 TvProgram program=new TvProgram(); 21 program.PlayTime=Convert.ToDateTime(tn["playTime"].InnerText); 22 program.Name = tn["programName"].InnerText; 23 program.ShiDuan = tn["meridien"].InnerText; 24 program.Path = tn["path"].InnerText; 25 26 TvList.Add(program); 27 } 28 } 29 } 30 }
B頻道
1 public class TypeBChannel:ChannelBase 2 { 3 public override void Fetch() 4 { 5 XmlDocument doc = new XmlDocument(); 6 doc.Load(Path); 7 if (TvList == null) 8 { 9 TvList = new List<TvProgram>(); 10 } 11 XmlElement root = doc.DocumentElement; 12 foreach (XmlNode item in root.ChildNodes) 13 { 14 foreach (XmlNode tn in item.ChildNodes) 15 { 16 TvProgram program = new TvProgram(); 17 program.PlayTime = Convert.ToDateTime(tn["playTime"].InnerText); 18 program.Name = tn["name"].InnerText; 19 20 program.Path = tn["path"].InnerText; 21 22 TvList.Add(program); 23 } 24 } 25
傳遞類
1 public class ChannelManager 2 { 3 private const string channelPath = "files/Fullchannels.xml"; 4 public ChannelManager() 5 { 6 this.fullChannel = new Dictionary<string, ChannelBase>(); 7 this.myChannelList=new SavingInfo(); 8 } 9 //所有頻道列表(string:名稱 ChannelBase:頻道父類) 10 private Dictionary<string, ChannelBase> fullChannel; 11 public Dictionary<string, ChannelBase> FullChannel 12 { 13 get { return fullChannel; } 14 set { fullChannel = value; } 15 } 16 17 public SavingInfo MyChannelList 18 { 19 get { return myChannelList; } 20 set { myChannelList = value; } 21 } 22 23 //保存我的電台 24 private SavingInfo myChannelList; 25 //加載所有頻道 26 public void LoadAllChannel() 27 { 28 XmlDocument doc=new XmlDocument(); 29 doc.Load(channelPath); 30 //獲取根節點 31 XmlElement root=doc.DocumentElement; 32 33 foreach (XmlNode item in root.ChildNodes) 34 { 35 //加上注釋!@@@@ 36 ChannelBase channel= ChannelFactory.CreateChannel(item["channelType"].InnerText); 37 foreach (XmlNode xmlNode in item.ChildNodes) 38 { 39 40 switch (xmlNode.Name) 41 { 42 case "tvChannel": 43 channel.ChannelName= xmlNode.InnerText; 44 break; 45 case "path": 46 channel.Path = xmlNode.InnerText; 47 break; 48 case "channelType": 49 channel.Type = xmlNode.InnerText; 50 break; 51 } 52 } 53 fullChannel.Add(channel.ChannelName,channel); 54 } 55 56 }
1 //簡單工廠 2 public static class ChannelFactory 3 { 4 public static ChannelBase CreateChannel(string type) 5 { 6 ChannelBase channel=null; 7 switch (type) 8 { 9 case "TypeA": 10 channel = new TypeAChannel(); 11 break; 12 case "TypeB": 13 channel = new TypeBChannel(); 14 break; 15 } 16 return channel; 17 } 18 }
1 //節目類 2 public class TvProgram 3 { 4 //播出時間 5 public DateTime PlayTime{ get; set; } 6 // 早間檔,午間檔,晚間檔 7 public string ShiDuan { get; set; } 8 public string Name { get; set; } 9 //視頻路徑 10 public string Path { get; set; } 11 }
1 public class SavingInfo 2 { 3 //構造函數 4 public SavingInfo() 5 { 6 this.ChannelList=new List<ChannelBase>(); 7 } 8 9 //我的收藏:定義了一個泛型集合,保存我的電台下所有的頻道 10 private List<ChannelBase> channelList; 11 12 public List<ChannelBase> ChannelList 13 { 14 get 15 { 16 return channelList; 17 } 18 set { channelList = value; } 19 } 20 }
完結待續。。。。。。。。。。。。。。。。