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>
<?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 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>
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; } }
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; } }
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); } }
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; } }
寫到這里,如果運行一下程序,會報錯誤
.
我們仔細回想一下,我們在給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流會繼續對該項目進行優化.或許我所做的并不完美,存在著許多代碼的復用和冗余,也希望看過的各位進行提點,幫助我獲取更多更優的解決方案.小子在此先行謝過了~~~
新聞熱點
疑難解答