轉眼2015年已經過去,我們有跌跌撞撞的闖入了2016年!看湖南衛視的跨年演唱會時何老師說“大家好好想一想2015年你收穫了什麼?” 回想2015年還是有些收穫的。從8月份的什麼都不懂到現在經過五個多月的學習已經可以獨立完成一個簡單的KTV點歌系統了(雖然不能聯網)!我覺得這就是我2015年最大的收...
轉眼2015年已經過去,我們有跌跌撞撞的闖入了2016年!看湖南衛視的跨年演唱會時何老師說“大家好好想一想2015年你收穫了什麼?”
回想2015年還是有些收穫的。從8月份的什麼都不懂到現在經過五個多月的學習已經可以獨立完成一個簡單的KTV點歌系統了(雖然不能聯網)!我覺得這就是我2015年最大的收穫!!
前臺運行效果展示
先給大家看一下這個系統的運行效果圖
主界面
該系統提供了5中點歌方式分別為 歌星點歌、拼音點歌、類型點歌、金曲排行和字數點歌
歌星點歌
該窗體有三個ListView視圖效果如下
點擊歌手則跳轉到歌曲列表並顯示該歌手的所有歌曲
如果選中點擊一首歌曲則判斷是否有其他歌曲正在播放如果有則直接將該歌曲加入到已點列表中如果沒有則直接播放該歌曲並加入已點列表
拼音點歌
拼音點歌可以根據歌曲名和歌曲名的拼音縮寫來進行點歌選中並點擊一首歌時效果同已點列表
類型點歌
類型點歌根據歌曲的類型進行點歌如果選中並點擊一個類型則跳轉到歌曲列表並顯示該類型的所有歌曲
金曲排行
金曲排行顯示所有的歌曲按照點播次數進行降序排序如果選中歌曲並點擊效果同已點列表
字數點歌
字數點歌通過歌曲名字的字數進行點歌
前臺技術實現
同一窗體顯示多種界面
使用三個ListView控制項展示不同的界面通過設置其Visible屬性來控制界面的顯示
if (listView2.Visible == true)//如果listView2顯示 { listView2.Visible = false;//將listView2隱藏 listView1.Visible = true;//將listView1顯示 } else if (lv1.Visible == true)//如果lv1顯示 { lv1.Visible = false;//將lv1隱藏 listView2.Visible = true//將listView2顯示 } else { listView1.Visible = false;//將listView1隱藏 lv1.Visible = true;//將lv1顯示 }
將歌曲添加到已點列表
該功能分三步實現
1.定義一個歌曲類並定義一個靜態的歌曲類數組
public class PlayList { public string name;//歌曲名 public string singername="未播放";//播放狀態 public string url;//歌曲路徑 } public class DBhelp { //歌曲對象數組 public static PlayList[] list = new PlayList[50]; }
2.將歌曲添加到數組中
//將傳進來的對象加入倒數組中 public static bool playadd(PlayList sb) { if (frmmain.songurl == "") { //如果當前沒有歌曲正在播放則包房該歌曲 frmmain.upsong = sb.name; frmmain.songurl = DBhelp.songurl() + "\\" + sb.url; DBhelp.f.seturl(); sb.singername = "正在播放"; } else { //判斷數組中的歌曲數量是否小於或等於兩首 int i = 0;//表示數組中個去的數量 foreach (var item in DBhelp.list) { i++; if (item == null) { break; } } if (i <= 2) { frmmain.buttomsong = sb.name;//將該歌曲的名字付給主窗體的靜態變數以便在“下一首”對應的文本框中顯示 } } for (int i = 0; i < DBhelp.list.Length; i++) { if (DBhelp.list[i]!=null) { //如果該歌曲在數組中已經存在則不再進行添加直接跳過 if (DBhelp.list[i].name==sb.name&&DBhelp.list[i].url==sb.url) { break; } } //找出數組中沒有存儲個去的一項並將該歌曲加入到該項中 else if (DBhelp.list[i]==null) { DBhelp.list[i] = sb; DBhelp.frm.add(); return true;//加入成功返回true } } return false;//加入失敗返回false }
3.將數組中的歌曲添加到已點列表
//將該方法放入到計時控制項(Timer)的Tick事件中 public void add() { listView1.Items.Clear();//清除已點列表中的現有項 //遍曆數組將數組中的所有歌曲添加到ListView控制項中 for (int i = 0; i <DBhelp.list.Length; i++) { if (DBhelp.list[i]!=null) { ListViewItem li = new ListViewItem(DBhelp.list[i].name); li.SubItems.Add(DBhelp.list[i].singername); li.SubItems.Add(DBhelp.list[i].url); listView1.Items.Add(li); } } }
使用WIndows Media Player控制項播放歌曲
wplist.URL = songurl; //wplist為該空間的name屬性名,songurl為歌曲的完整路徑字元串 //通過設置wplist的URL屬性可以播放指定路徑的歌曲
控制歌曲的播放狀態
個人覺得歌曲的播放狀態的控制是很費精力的也是本次項目花費時間最長的一個模塊
//提前定義一個靜態變數index用來標示整的播放歌曲的索引 // 實現播放等功能 public void qiesong() { if (DBhelp.list[frmmain.index] != null) { //該下標的歌曲不為空 DBhelp.list[frmmain.index].singername = "正在播放"; frmmain.upsong = DBhelp.list[frmmain.index].name;//upsong標示正在播放歌曲的名字 frmmain.songurl = DBhelp.songurl() + "\\" + DBhelp.list[frmmain.index].url;//songurl標示正在播放歌曲的完整路徑 } else { //該下標的歌曲為空 frmmain.index = 0; DBhelp.list[frmmain.index].singername = "正在播放"; frmmain.upsong = DBhelp.list[frmmain.index].name; frmmain.songurl =DBhelp.songurl()+"\\"+ DBhelp.list[frmmain.index].url; } if (DBhelp.list[frmmain.index + 1] != null) { //該下標的下一個歌曲不為空 frmmain.buttomsong = DBhelp.list[frmmain.index + 1].name;//buttomsong標示下一首播放的歌曲的名字 } else { //該下標的下一個歌曲為空 frmmain.buttomsong = DBhelp.list[0].name; } DBhelp.f.seturl();//seturl方法用於給播放器控制項設置路徑 }
●切歌
//實現切歌功能 public void clickgetsongstly() { if (listView1.Items.Count > 0) { DBhelp.list[frmmain.index].singername = "已播放"; frmmain.index += 1; qiesong(); } }
●播放
if (listView1.SelectedItems.Count > 0) { DBhelp.list[frmmain.index].singername = "已播放"; frmmain.index = listView1.Items.IndexOf(listView1.SelectedItems[0]);//獲取選中的歌曲的下標 qiesong(); } else { MessageBox.Show("請選擇一首歌曲"); }
●刪除
if (listView1.SelectedItems.Count>0) { int index = listView1.Items.IndexOf(listView1.SelectedItems[0]);//獲取選中歌曲的下標 listView1.Items.Remove(listView1.SelectedItems[0]);在ListView控制項中清除該歌曲 string state = DBhelp.list[index].singername;//獲取選中歌曲的狀態 DBhelp.list[index] = null;//在數組中刪除該歌曲 int starteindex=0;//標示正在播放歌曲的下標 for (int i = index; i <DBhelp.list.Length-1; i++) { //將刪除歌曲之後的歌曲前移 DBhelp.list[i] = DBhelp.list[i + 1]; DBhelp.list[i + 1] = null; } for (int j = 0; j <DBhelp.list.Length-1; j++) {//獲取正在播放的歌曲的下標 if (DBhelp.list[j]!=null) { if ( DBhelp.list[j].singername == "正在播放") { starteindex = j; } } } if (state=="正在播放") {//刪除歌曲的狀態為正在播放 if (index!=0) {//選中歌曲的下標不為0 frmmain.index -= 1; clickgetsongstly(); } else if (listView1.Items.Count < 1) {//選中歌曲的下標為0並且已點列表中沒有歌曲 frmmain.index = 0; frmmain.upsong = ""; frmmain.songurl = ""; frmmain.buttomsong = ""; DBhelp.f.seturl(); } else {//選中歌曲的下標為0並且已點列表中有歌曲 frmmain.index = 0; qiesong(); } }else if (listView1.Items.Count<=1) { frmmain.buttomsong = DBhelp.list[0].name; } else { //刪除歌曲的狀態不為正在播放 frmmain.index = starteindex; if (DBhelp.list[frmmain.index + 1] != null) {//刪除歌曲的下標的下一項有歌曲 frmmain.buttomsong = DBhelp.list[frmmain.index + 1].name; } else { //刪除歌曲的下標的下一項沒有歌曲 frmmain.buttomsong = DBhelp.list[0].name; } } add(); } else { MessageBox.Show("請選擇一首歌曲"); }
窗體邊框樣式設置為None時窗體可以移動
private Point mouseOffset; //記錄滑鼠指針的坐標 private bool isMouseDown = false; //記錄滑鼠按鍵是否按下 //Point 提供有序的 x 坐標和 y 坐標整數對,該坐標對在二維平面中定義一個點。 //滑鼠左鍵按下後發生 private void SelectSongFromClassify_MouseDown(object sender, MouseEventArgs e) { int xOffset; int yOffset; if (e.Button == MouseButtons.Left) { xOffset = -e.X - SystemInformation.FrameBorderSize.Width; yOffset = -e.Y - SystemInformation.CaptionHeight - SystemInformation.FrameBorderSize.Height; mouseOffset = new Point(xOffset, yOffset); isMouseDown = true; } } //滑鼠在組件上移動時發生 private void SelectSongFromClassify_MouseMove(object sender, MouseEventArgs e) { if (isMouseDown) { Point mousePos = Control.MousePosition; mousePos.Offset(mouseOffset.X + 5, mouseOffset.Y + 30); Location = mousePos; } } //滑鼠左鍵按下並釋放後發生 private void SelectSongFromClassify_MouseUp(object sender, MouseEventArgs e) { // 修改滑鼠狀態isMouseDown的值 // 確保只有滑鼠左鍵按下並移動時,才移動窗體 if (e.Button == MouseButtons.Left) { isMouseDown = false; } }
結尾
好了,今天就先寫這麼多吧!關於後臺方面的下次再寫吧(寫的眼睛疼~~~)!!!