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; } }
结尾
好了,今天就先写这么多吧!关于后台方面的下次再写吧(写的眼睛疼~~~)!!!