首页 > 学院 > 开发设计 > 正文

MyKTV项目,走起!

2019-11-14 15:53:28
字体:
来源:转载
供稿:网友

MyKTV项目,走起!

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

话不多说,先上类图:

接着是数据库表间关系:

 

本项目要实现以下功能:

  1. 明星点歌
  2. 拼音点歌
  3. 类型选择
  4. 金榜排行
  5. 字数点歌

一共五大块,那么明星点歌下还有一个播放的功能。

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

这是ktv主页面:

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

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

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

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

 

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

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

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

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

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

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

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

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

刷新歌曲列表代码:

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

 

明星点歌代码:

  1      string singertype = "组合";  2         int singertypid = 0;  3   4      /// <summary>  5         /// 第一层listView  6         /// </summary>  7         public void LoadSingerArea()   8         {  9             if (lvType.SelectedItems[0]!=null) 10             { 11                 lvType.Visible = false; 12                 lvCountry.Visible = true; 13                 lvCountry.Location = lvType.Location; 14                 lvCountry.Dock = DockStyle.Fill; 15                 this.singertype = Convert.ToString(lvType.SelectedItems[0].Text); 16             }                     17             string sql = "select singertype_id,singertype_name from singer_type"; 18             SqlCommand cmd = new SqlCommand(sql,db.Connection ); 19             try 20             { 21                 db.OpenConnection(); 22                 SqlDataReader dr = cmd.ExecuteReader(); 23                 lvCountry.Items.Clear(); 24                 if (dr.HasRows) 25                 { 26                     int index = 0; 27                     while (dr.Read()) 28                     { 29                         ListViewItem lvitem = new ListViewItem(); 30                         int typeid = Convert.ToInt32(dr["singertype_id"]); 31                         string typename = Convert.ToString(dr["singertype_name"]); 32                         lvitem.Text = typename; 33                         lvitem.Tag = typeid; 34                         lvitem.ImageIndex = index; 35                         lvCountry.Items.Add(lvitem); 36                         index++; 37                     } 38                 } 39                 dr.Close(); 40             } 41             catch (Exception ex) 42             { 43  44                 MessageBox.Show(ex.Message); 45             } 46             finally 47             { 48                 db.CloseConnection(); 49             } 50         } 51         /// <summary> 52         /// 第二层listView 53         /// </summary> 54         public void LoadSingerName()  55         { 56             if (lvCountry.SelectedItems[0]!=null) 57             { 58                 //隐藏歌手地区,显示歌手的姓名 59                 lvCountry.Visible = false; 60                 lvSinger.Visible = true; 61                 lvSinger.Location = lvCountry.Location;                                62                 singertypid = Convert.ToInt32(lvCountry.SelectedItems[0].Tag); 63                 StringBuilder sql = new StringBuilder(); 64                 string result = singertype; 65                 if (result!="组合") 66                 { 67                     result = singertype == "女歌手" ? "" : ""; 68                 } 69                 sql.AppendFormat("select singe_id,singer_name,singer_photo_url from Singer_info where singertype_id={0}and singer_gemder='{1}'",singertypid,result); 70                 SqlCommand cmd = new SqlCommand(sql.ToString(), db.Connection); 71                 try 72                 {                     73                     db.OpenConnection(); 74                     SqlDataReader dr = cmd.ExecuteReader(); 75                     int imageIndex = 0; //代表歌手头像的索引 76                     imageList1.Images.Clear(); 77                     lvSinger.Items.Clear(); 78                     if (dr.HasRows) 79                     { 80                         while (dr.Read()) 81                         { 82                              string photoURL = KTVUtil.singerPhotoPath + "//" + Convert.ToString(dr["singer_photo_url"]); 83                             imageList1.Images.Add(Image.FromFile(photoURL)); 84                             ListViewItem item = new ListViewItem(); 85                             item.Text = Convert.ToString(dr["singer_name"]); 86                             item.Tag = Convert.ToString(dr["singer_id"]); 87                             item.ImageIndex = imageIndex; 88                             lvSinger.Items.Add(item); 89                             imageIndex++; 90                         } 91                     } 92                     dr.Close(); 93                 } 94                 catch (Exception ex) 95                 { 96                     MessageBox.Show(ex.Message); 97                 } 98                 finally  99                 {100                     db.CloseConnection();101                 }102             }103         }104 105         private void tsplMenu_Click(object sender, EventArgs e)106         {107             MainForm mf = new MainForm();108             mf.Show();109             this.Close();110 111         }112         /// <summary>113         /// 第三层listView114         /// </summary>115         public void SongList()116         {117             StringBuilder sb = new StringBuilder();118             sb.AppendFormat("select song_id,song_name, singer_name='{0}',song_url  from SongInfo,Singer_Info where singer_id={1}",119                 lvSinger.SelectedItems[0].Text, Convert.ToInt32(lvSinger.SelectedItems[0].Tag));120 121             SongListForm songList = new SongListForm();122             songList.Sql = sb.ToString();123             songList.Show();124             this.Close();125         }

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

 1      private void lvType_Click(object sender, EventArgs e) 2         { 3             LoadSingerArea(); 4         } 5  6         private void lvSinger_Click(object sender, EventArgs e) 7         { 8             SongList(); 9         }10 11         private void lvCountry_Click(object sender, EventArgs e)12         {13             LoadSingerName();14         }

播放过程:

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

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

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

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

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

接下来是拼音点歌

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

拼音点歌部分代码:

 1         // 查询歌曲显示在窗体中 2         private void btnSearch_Click(object sender, EventArgs e) 3         {                        4             DBHelper dbHelper = new DBHelper(); 5             DataSet dataSet = new DataSet(); 6             StringBuilder sb = new StringBuilder(); 7             sb.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 "); 8             sb.AppendFormat("where song_name like '%{0}%' or song_ab like '{0}'",this.txtSongName.Text); 9 10             Console.WriteLine(sb.ToString());11 12             SqlDataAdapter adapter = new SqlDataAdapter(sb.ToString(), dbHelper.Connection);13 14              // 清空当前列表15             if (dataSet.Tables["songList"] != null)16             {17                 dataSet.Tables["songList"].Clear();18             }19 20             adapter.Fill(dataSet, "songList");21             this.dgvSong.DataSource = dataSet.Tables["songList"];            22         }

类型点歌:

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

 

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

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

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

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

 1         for (int i = 1; i <= 5; i++)//行数 2              { 3                 for (int j = 1; j <= 5; j++) 4                 { 5                     Label label = new Label(); 6                     label.Text = i+"-"+j; 7                     //自身大小(重点) 8                     label.Size = new Size(80, 50); 9                     //背景颜色10                     label.BackColor = Color.Yellow;11                     //相对于窗体0,0点的位置12                     label.Location = new Point(20+100*j, 20+80*i);13                     //文本居中14                     label.TextAlign = ContentAlignment.MiddleCenter;15                     //字体大小16                     label.Font=new Font("Bradley Hand ITC",20);17                     //触发Click事件18                     label.Click += label_Click;19                    20                     //让Label对象归属于当前窗体21                     this.Controls.Add(label);22                 }23             }24 25         }26 27         void label_MouseMove(object sender, MouseEventArgs e)28         {29             this.Text = e.X + "" + e.Y;30         }31 32         void label_Click(object sender, EventArgs e)33         {34            35             Label label = (Label)sender;36             MessageBox.Show(label.Text);37             38 39         }40 41         private void Form1_MouseMove(object sender, MouseEventArgs e)42         {43             this.Text = e.X + "" + e.Y;44         }

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

 

第二部分:

部分关键代码如下:

1.重唱:

1 // 重新播放当前歌曲2         private void tsbtnAgain_Click(object sender, EventArgs e)3         {4             PlayList.PlayAgain();5         }

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

2.切歌:

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

3.播放:

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

 

4.PlayList类:

  1 /// <summary>  2     /// 播放列表管理  3     /// </summary>  4     class PlayList  5     {  6         private static Song[] songList = new Song[50]; // 歌曲播放列表数组  7         private static int songIndex = 0;  // 当前播放的歌曲在数组中的索引        8   9         /// <summary> 10         /// 播放列表数组 11         /// </summary> 12         public static Song[] SongList 13         { 14           get { return PlayList.songList; }           15         } 16  17         /// <summary> 18         /// 当前播放歌曲的索引 19         /// </summary> 20         public static int SongIndex 21         { 22             get { return PlayList.songIndex; } 23         } 24  25         /// <summary> 26         /// 当前播放的歌曲名称 27         /// </summary> 28         /// <returns>歌曲名称</returns> 29         public static string PlayingSongName() 30         {  31             string songName = ""; // 歌曲名称 32             if (SongList[SongIndex] != null) 33             { 34                 songName = SongList[SongIndex].SongName; 35             } 36  37             return songName; 38         } 39  40         /// <summary> 41         /// 获取当前播放的歌曲 42         /// </summary> 43         /// <returns>当前要播放的歌曲</returns> 44         public static Song GetPlayingSong() 45         { 46             if (SongList[songIndex] != null) 47             { 48                 return SongList[songIndex]; 49             } 50             else 51             { 52                 return null; 53             } 54         } 55  56         /// <summary> 57         /// 下一首要播放的歌曲名称 58         /// </summary> 59         /// <returns>歌曲名称</returns> 60         public static string NextSongName() 61         { 62             string songName = ""; // 歌曲名称 63             if (SongList[SongIndex+1] != null) 64             { 65                 songName = SongList[SongIndex+1].SongName; 66             } 67  68             return songName; 69         } 70          71         /// <summary> 72         /// 点播一首歌曲 73         /// </summary> 74         /// <param name="song">新点播的歌曲</param> 75         public static bool AddSong(Song song) 76         { 77             bool success = false; 78             for (int i = 0; i < SongList.Length; i++) 79             { 80                 if (SongList[i] == null) 81                 { 82                     SongList[i] = song; 83                     Console.WriteLine(song.SongName); 84                     success = true; 85                     break; 86                 } 87             } 88  89             return success; 90         } 91  92         /// <summary> 93         /// 切歌 94         /// </summary> 95         /// <param name="index">要切歌曲的编号,如果是切当前播放的歌曲传入-1</param> 96         public static void CutSong(int index) 97         { 98             int i;  // 循环变量,代表切歌的位置 99             if (index == -1)100             {101                 i = SongIndex;                102             }103             else104             { 105                 i = index; // 从切歌的位置开始,将歌曲逐个向前移一个位置106             }107 108             SongList[i].SetSongCut();109             while (SongList[i] != null)110             {111                 SongList[i] = SongList[i + 1];   112                 i++;113 114                 // 如果到达数组最后一个元素,就将最后一个元素指向空115                 if (i == SongList.Length)116                 {117                     SongList[i] = null;118                 }119             }120         }121 122         /// <summary>123         /// 重放当前歌曲124         /// </summary>125         public static void PlayAgain()126         {127             if (SongList[songIndex] != null)128             {129                 SongList[songIndex].SetPlayAgain();130             }131         }132 133         /// <summary>134         /// 播放下一首135         /// </summary>136         public static void MoveOn()137         {138             if (SongList[songIndex] != null && SongList[songIndex].PlayState == SongPlayState.again)139             {140                 SongList[songIndex].SetSongPlayed();141             }142             else143             {144                 songIndex++;145             }            146         }       147     }

 

5.Song类:

 1     enum SongPlayState 2     {  3         unplayed,played,again,cut   4     } 5      6      7     /// <summary> 8     /// 歌曲类 9     /// </summary>10     class Song11     {        12         /// <summary>13         /// 歌曲名称14         /// </summary>15         public string SongName16         {17             get { return songName; }18             set { songName = value; }19         }20 21         /// <summary>22         /// 歌曲存放路径23         /// </summary>24         public string SongURL25         {26             get { return songURL; }27             set { songURL = value; }28         }29 30         /// <summary>31         /// 歌曲播放状态32         /// </summary>33         internal SongPlayState PlayState34         {35             get { return playState; }36             set { playState = value; }37         }38         39         private string songName;40         private string songURL;41         private SongPlayState playState = SongPlayState.unplayed;  // 歌曲播放状态42 43         44         /// <summary>45         /// 将歌曲状态改为已播放46         /// </summary>47         public void SetSongPlayed()48         {49             this.playState = SongPlayState.played;50         }51 52         /// <summary>53         /// 将歌曲状态改为再拨放一次54         /// </summary>55         public void SetPlayAgain()56         {57             this.playState = SongPlayState.again;58         }59 60         /// <summary>61         /// 将歌曲状态改为切歌62         /// </summary>63         public void SetSongCut()64         {65             this.playState = SongPlayState.cut;66         }67     }

6.KTVUtil类:

这里主要存的就是路径

1         public static string singerPhotoPath = "";  // 歌手照片路径2         public static string songPath = "";         // 歌曲路径

7.SongList类:

 1 public enum PalySongState  2     { 3        //未播放 , 播放, 重播,切歌 4        unplayed,played,again,cut 5     } 6     /// <summary> 7     /// 歌曲播放类 8     /// </summary> 9      public class SongList10     {11          //歌曲名称12         private string SongName;13          //歌曲路径14         private string SongUl;15          //歌曲状态16         private string SongState;17 18         public string SongState119         {20             get { return SongState; }21             set { SongState = value; }22         }23 24         public string SongUl125         {26             get { return SongUl; }27             set { SongUl = value; }28         }29 30         public string SongName131         {32             get { return SongName; }33             set { SongName = value; }34         }35 36          //把当前的播放状态设置为未播放状态37        private  PalySongState playSong = PalySongState.unplayed;38 39         public  PalySongState PlaySong40         {41             get { return playSong; }42             set { playSong = value; }43         }44          /// <summary>45          /// 将未播放状态改为播放状态46          /// </summary>47         public void PalyState() 48         {49             this.PlaySong = PalySongState.played;50         }51          /// <summary>52          /// 将歌曲重新播放53          /// </summary>54         public void AgainState() 55         {56             this.PlaySong = PalySongState.again;57         }58          /// <summary>59          /// 切歌状态60          /// </summary>61         public void CutState() 62         {63             this.PlaySong = PalySongState.cut;64         }65     }

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

把前台和后台连在一起。

 


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表