分享
 
 
 

MyKTV项目,走起!

王朝学院·作者佚名  2016-08-27
窄屏简体版  字體: |||超大  

MyKTV项目,走起!

第一部分:这个项目对于新手来说有一点难度,但是当你理清类之间的关系和怎样去实现功能后就会感觉轻松很多。

话不多说,先上类图:

接着是数据库表间关系:

本项目要实现以下功能:

明星点歌拼音点歌类型选择金榜排行字数点歌一共五大块,那么明星点歌下还有一个播放的功能。

在主页面有一个正在播放和下一首的提示功能。

这是ktv主页面:

在下边还有重唱,切歌,已点,服务和退出功能

相信大家都去过KTV,所以这些功能就不说了,比我都清楚!

这里我把播放控件放在了主页面,位置随意,放在哪都行,也可以单独开一个窗体进行播放。

点击明星点歌进入到明星点歌页面:

组合,女歌手和男歌手都放在listView中,这里要注意的是在这一个窗体中一共有三个listView,先在窗体中隐藏后两个,

那么点击第一个进入到第二个时要把第一个listView隐藏。

隐藏listView只需把它的Visible属性设置成false就ok了:

1lvCountry.Visible =false;2lvSinger.Visible =false;

第二个listView就是供用户一个更精确的选择歌曲或歌手了:

第三个listView就是显示歌手对应的图片:

这个图片要从数据库中取,不能写死,还有很多功能,像金榜排行,都不能写死。

再次点击就进入播放列表:

刷新歌曲列表代码:

1///<summary>2///刷新歌曲列表3///</summary>4PRivatevoidRefreshSongList()5{6lvSongList.Items.Clear();//清空原列表7inti =0;8while(PlayList.SongList[i] !=null)9{10ListViewItem item =newListViewItem();11item.Text =PlayList.SongList[i].SongName;12item.Tag =i;13stringplayState = PlayList.SongList[i].PlayState== SongPlayState.unplayed?"未播放":"已播放";14item.SubItems.Add(playState);15lvSongList.Items.Add(item);16i++;17}18}

明星点歌代码:

1stringsingertype ="组合";2intsingertypid =0;34///<summary>5///第一层listView6///</summary>7publicvoidLoadSingerArea()8{9if(lvType.SelectedItems[0]!=null)10{11lvType.Visible =false;12lvCountry.Visible =true;13lvCountry.Location =lvType.Location;14lvCountry.Dock =DockStyle.Fill;15this.singertype = Convert.ToString(lvType.SelectedItems[0].Text);16}17stringsql ="select singertype_id,singertype_name from singer_type";18SqlCommand cmd =newSqlCommand(sql,db.Connection );19try20{21db.OpenConnection();22SqlDataReader dr =cmd.ExecuteReader();23lvCountry.Items.Clear();24if(dr.HasRows)25{26intindex =0;27while(dr.Read())28{29ListViewItem lvitem =newListViewItem();30inttypeid = Convert.ToInt32(dr["singertype_id"]);31stringtypename = Convert.ToString(dr["singertype_name"]);32lvitem.Text =typename;33lvitem.Tag =typeid;34lvitem.ImageIndex =index;35lvCountry.Items.Add(lvitem);36index++;37}38}39dr.Close();40}41catch(Exception ex)42{4344MessageBox.Show(ex.Message);45}46finally47{48db.CloseConnection();49}50}51///<summary>52///第二层listView53///</summary>54publicvoidLoadSingerName()55{56if(lvCountry.SelectedItems[0]!=null)57{58//隐藏歌手地区,显示歌手的姓名59lvCountry.Visible =false;60lvSinger.Visible =true;61lvSinger.Location =lvCountry.Location;62singertypid = Convert.ToInt32(lvCountry.SelectedItems[0].Tag);63StringBuilder sql =newStringBuilder();64stringresult =singertype;65if(result!="组合")66{67result = singertype =="女歌手"?"女":"男";68}69sql.AppendFormat("select singe_id,singer_name,singer_photo_url from Singer_info where singertype_id={0}and singer_gemder='{1}'",singertypid,result);70SqlCommand cmd =newSqlCommand(sql.ToString(), db.Connection);71try72{73db.OpenConnection();74SqlDataReader dr =cmd.ExecuteReader();75intimageIndex =0;//代表歌手头像的索引76imageList1.Images.Clear();77lvSinger.Items.Clear();78if(dr.HasRows)79{80while(dr.Read())81{82stringphotoURL = KTVUtil.singerPhotoPath +"\\"+ Convert.ToString(dr["singer_photo_url"]);83imageList1.Images.Add(Image.FromFile(photoURL));84ListViewItem item =newListViewItem();85item.Text = Convert.ToString(dr["singer_name"]);86item.Tag = Convert.ToString(dr["singer_id"]);87item.ImageIndex =imageIndex;88lvSinger.Items.Add(item);89imageIndex++;90}91}92dr.Close();93}94catch(Exception ex)95{96MessageBox.Show(ex.Message);97}98finally99{100db.CloseConnection();101}102}103}104105privatevoidtsplMenu_Click(objectsender, EventArgs e)106{107MainForm mf =newMainForm();108mf.Show();109this.Close();110111}112///<summary>113///第三层listView114///</summary>115publicvoidSongList()116{117StringBuilder sb =newStringBuilder();118sb.AppendFormat("select song_id,song_name, singer_name='{0}',song_url from SongInfo,Singer_Info where singer_id={1}",119lvSinger.SelectedItems[0].Text, Convert.ToInt32(lvSinger.SelectedItems[0].Tag));120121SongListForm songList =newSongListForm();122songList.Sql =sb.ToString();123songList.Show();124this.Close();125}

之后一定要在listView的Click事件中调用方法:

1privatevoidlvType_Click(objectsender, EventArgs e)2{3LoadSingerArea();4}56privatevoidlvSinger_Click(objectsender, EventArgs e)7{8SongList();9}1011privatevoidlvCountry_Click(objectsender, EventArgs e)12{13LoadSingerName();14}

播放过程:

当选中某首歌曲后,点击一下,那么就会将各个列的值拼接成一个Song对象,

1Song song=newSong();2song.songName="值";3song.songUrl="地址";

歌曲列表中数据来源于数据库!所以我们要将喜欢的歌曲添加到数据库中!

当我们点击已点的时候就会循环遍历数组,然后每遍历一项,就会创建一个 ListViewItem对象。

刚才忘了说了,每个页面下面的菜单我用的是ToolStrip控件。

接下来是拼音点歌。

拼音点歌相对来说就简单多了,就是一个模糊查询,页面如下:

拼音点歌部分代码:

1//查询歌曲显示在窗体中2privatevoidbtnSearch_Click(objectsender, EventArgs e)3{4DBHelper dbHelper =newDBHelper();5DataSet dataSet =newDataSet();6StringBuilder sb =newStringBuilder();7sb.Append("select song_id,song_name,singer_name,song_url from song_info inner join singer_info on singer_info.singer_id=song_info.singer_id");8sb.AppendFormat("where song_name like '%{0}%' or song_ab like '{0}'",this.txtSongName.Text);910Console.WriteLine(sb.ToString());1112SqlDataAdapter adapter =newSqlDataAdapter(sb.ToString(), dbHelper.Connection);1314//清空当前列表15if(dataSet.Tables["songList"] !=null)16{17dataSet.Tables["songList"].Clear();18}1920adapter.Fill(dataSet,"songList");21this.dgvSong.DataSource = dataSet.Tables["songList"];22}

类型点歌:

这个和酷狗里的如下页面功能类似:

点击某一个项进入到相应的歌曲页面,部分代码如下:

1//窗体加载时,显示歌曲类别2privatevoidOrderBySongTypeForm_Load(objectsender, EventArgs e)3{4//读取歌曲类别5DBHelper dbHelper =newDBHelper();6stringsql ="select * from song_type";7try8{9//查询数据库10SqlCommand command =newSqlCommand(sql, dbHelper.Connection);11dbHelper.OpenConnection();12SqlDataReader reader =command.ExecuteReader();1314//循环将类别读取出来添加到ListView中15this.lvSongType.Items.Clear();16inti =0;17while(reader.Read())18{19ListViewItem item =newListViewItem();20item.Text = Convert.ToString(reader["songtype_name"]);21item.Tag = Convert.ToInt32(reader["songtype_id"]);22item.ImageIndex =i;23this.lvSongType.Items.Add(item);24i++;25}26reader.Close();27}28catch(Exception ex)29{30Console.WriteLine(ex.Message);31MessageBox.Show("系统错误,请联系服务人员!");3233}34finally35{36dbHelper.CloseConnection();37}38}

金榜排行和字数点歌大家可以尝试着写一下,都不难!字数点歌这里要注意一下:

上边的那12个Label不是拖12个Label控件,而是利用二重数组进行控制Label的:

1for(inti =1; i <=5; i++)//行数2{3for(intj =1; j <=5; j++)4{5Label label =newLabel();6label.Text = i+"-"+j;7//自身大小(重点)8label.Size =newSize(80,50);9//背景颜色10label.BackColor =Color.Yellow;11//相对于窗体0,0点的位置12label.Location =newPoint(20+100*j,20+80*i);13//文本居中14label.TextAlign =ContentAlignment.MiddleCenter;15//字体大小16label.Font=new Font("Bradley Hand ITC",20);17//触发Click事件18label.Click +=label_Click;1920//让Label对象归属于当前窗体21this.Controls.Add(label);22}23}2425}2627voidlabel_MouseMove(objectsender, MouseEventArgs e)28{29this.Text = e.X +","+e.Y;30}3132voidlabel_Click(objectsender, EventArgs e)33{3435Label label = (Label)sender;36MessageBox.Show(label.Text);373839}4041privatevoidForm1_MouseMove(objectsender, MouseEventArgs e)42{43this.Text = e.X +","+e.Y;44}

要记住:每一个控件都是一个类。

第二部分:

部分关键代码如下:

1.重唱:

1//重新播放当前歌曲2privatevoidtsbtnAgain_Click(objectsender, EventArgs e)3{4PlayList.PlayAgain();5}

就是调用PlayList中的PlayAgain()方法。PlayList类我会在下面给出。

2.切歌:

1//切歌2privatevoidtsbtnCut_Click(objectsender, EventArgs e)3{4if(MessageBox.Show("确定要切歌吗?","操作提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) ==DialogResult.OK)5{6intsongId = -1;//切歌的编号7if(this.lvSongList.SelectedItems.Count >0)8{9songId = Convert.ToInt32(this.lvSongList.SelectedItems[0].Tag);10}11PlayList.CutSong(songId);12this.RefreshSongList();13}14}

3.播放:

1privateSong song;//当前播放的歌曲2//播放歌曲3privatevoidPlaySong()4{5this.song = PlayList.GetPlaySong();//获取当前播放的歌曲6if(song !=null)7{8this.song.SetSongPlayed();//已播放9//D:\song\恋爱新手.mp310Player1.URL = KTVUtil.songPath +"\\"+this.song.SongURL;//得到当前播放歌曲的路径11txtNext.Text =this.song.SongName;12}13}

4.PlayList类:

1///<summary>2///播放列表管理3///</summary>4classPlayList5{6privatestaticSong[] songList =newSong[50];//歌曲播放列表数组7privatestaticintsongIndex =0;//当前播放的歌曲在数组中的索引89///<summary>10///播放列表数组11///</summary>12publicstaticSong[] SongList13{14get{returnPlayList.songList; }15}1617///<summary>18///当前播放歌曲的索引19///</summary>20publicstaticintSongIndex21{22get{returnPlayList.songIndex; }23}2425///<summary>26///当前播放的歌曲名称27///</summary>28///<returns>歌曲名称</returns>29publicstaticstringPlayingSongName()30{31stringsongName ="";//歌曲名称32if(SongList[SongIndex] !=null)33{34songName =SongList[SongIndex].SongName;35}3637returnsongName;38}3940///<summary>41///获取当前播放的歌曲42///</summary>43///<returns>当前要播放的歌曲</returns>44publicstaticSong GetPlayingSong()45{46if(SongList[songIndex] !=null)47{48returnSongList[songIndex];49}50else51{52returnnull;53}54}5556///<summary>57///下一首要播放的歌曲名称58///</summary>59///<returns>歌曲名称</returns>60publicstaticstringNextSongName()61{62stringsongName ="";//歌曲名称63if(SongList[SongIndex+1] !=null)64{65songName = SongList[SongIndex+1].SongName;66}6768returnsongName;69}7071///<summary>72///点播一首歌曲73///</summary>74///<param name="song">新点播的歌曲</param>75publicstaticboolAddSong(Song song)76{77boolsuccess =false;78for(inti =0; i < SongList.Length; i++)79{80if(SongList[i] ==null)81{82SongList[i] =song;83Console.WriteLine(song.SongName);84success =true;85

break;86}87}8889returnsuccess;90}9192///<summary>93///切歌94///</summary>95///<param name="index">要切歌曲的编号,如果是切当前播放的歌曲传入-1</param>96publicstaticvoidCutSong(intindex)97{98inti;//循环变量,代表切歌的位置99if(index == -1)100{101i =SongIndex;102}103else104{105i = index;//从切歌的位置开始,将歌曲逐个向前移一个位置106}107108SongList[i].SetSongCut();109while(SongList[i] !=null)110{111SongList[i] = SongList[i +1];112i++;113114//如果到达数组最后一个元素,就将最后一个元素指向空115if(i ==SongList.Length)116{117SongList[i] =null;118}119}120}121122///<summary>123///重放当前歌曲124///</summary>125publicstaticvoidPlayAgain()126{127if(SongList[songIndex] !=null)128{129SongList[songIndex].SetPlayAgain();130}131}132133///<summary>134///播放下一首135///</summary>136publicstaticvoidMoveOn()137{138if(SongList[songIndex] !=null&& SongList[songIndex].PlayState ==SongPlayState.again)139{140SongList[songIndex].SetSongPlayed();141}142else143{144songIndex++;145}146}147}

5.Song类:

1enumSongPlayState2{3unplayed,played,again,cut4}567///<summary>8///歌曲类9///</summary>10classSong11{12///<summary>13///歌曲名称14///</summary>15publicstringSongName16{17get{returnsongName; }18set{ songName =value; }19}2021///<summary>22///歌曲存放路径23///</summary>24publicstringSongURL25{26get{returnsongURL; }27set{ songURL =value; }28}2930///<summary>31///歌曲播放状态32///</summary>33internalSongPlayState PlayState34{35get{returnplayState; }36set{ playState =value; }37}3839privatestringsongName;40privatestringsongURL;41privateSongPlayState playState = SongPlayState.unplayed;//歌曲播放状态424344///<summary>45///将歌曲状态改为已播放46///</summary>47publicvoidSetSongPlayed()48{49this.playState =SongPlayState.played;50}5152///<summary>53///将歌曲状态改为再拨放一次54///</summary>55publicvoidSetPlayAgain()56{57this.playState =SongPlayState.again;58}5960///<summary>61///将歌曲状态改为切歌62///</summary>63publicvoidSetSongCut()64{65this.playState =SongPlayState.cut;66}67}

6.KTVUtil类:

这里主要存的就是路径

1publicstaticstringsingerPhotoPath ="";//歌手照片路径2publicstaticstringsongPath ="";//歌曲路径

7.SongList类:

1publicenumPalySongState2{3//未播放 , 播放, 重播,切歌4unplayed,played,again,cut5}6///<summary>7///歌曲播放类8///</summary>9publicclassSongList10{11//歌曲名称12privatestringSongName;13//歌曲路径14privatestringSongUl;15//歌曲状态16privatestringSongState;1718publicstringSongState119{20get{returnSongState; }21set{ SongState =value; }22}2324publicstringSongUl125{26get{returnSongUl; }27set{ SongUl =value; }28}2930publicstringSongName131{32get{returnSongName; }33set{ SongName =value; }34}3536//把当前的播放状态设置为未播放状态37privatePalySongState playSong =PalySongState.unplayed;3839publicPalySongState PlaySong40{41get{returnplaySong; }42set{ playSong =value; }43}44///<summary>45///将未播放状态改为播放状态46///</summary>47publicvoidPalyState()48{49this.PlaySong =PalySongState.played;50}51///<summary>52///将歌曲重新播放53///</summary>54publicvoidAgainState()55{56this.PlaySong =PalySongState.again;57}58///<summary>59///切歌状态60///</summary>61publicvoidCutState()62{63this.PlaySong =PalySongState.cut;64}65}

那么以上就是本次的KTV项目了,这个只是前台,那么大家也可以写一个后台进行管理和维护前台,通过数据库就可以

把前台和后台连在一起。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有