MyKTV前后台点歌管理系统
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MyKTV前后台点歌管理系统相关的知识,希望对你有一定的参考价值。
前台管理
主界面:
主要代码:
1 2 private void MainForm_Load(object sender, EventArgs e) 3 { 4 // 加载时,运行播放窗体 5 FrmPlay playForm = new FrmPlay(); 6 playForm.Show(); 7 8 // 启动定时器 9 this.timer1.Start(); 10 11 // 读取资源路径 12 DBHelper dbHelper = new DBHelper(); 13 string sql = "select resource_path from resource_path where resource_type = ‘singer_photo‘"; 14 SqlCommand command = new SqlCommand(sql, dbHelper.Connection); 15 16 // 读取歌手照片路径 17 try 18 { 19 dbHelper.OpenConnection(); 20 KTVUtil.singerPhotoPath = command.ExecuteScalar().ToString(); 21 } 22 catch (Exception ex) 23 { 24 MessageBox.Show("资源路径发生错误!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); 25 } 26 finally 27 { 28 dbHelper.CloseConnection(); 29 } 30 31 // 读取歌曲路径 32 sql = "select resource_path from resource_path where resource_type = ‘song‘"; 33 command.CommandText = sql; 34 try 35 { 36 dbHelper.OpenConnection(); 37 KTVUtil.songPath = command.ExecuteScalar().ToString(); 38 } 39 catch (Exception ex) 40 { 41 MessageBox.Show("路径错误", MessageBoxButtons.OK, MessageBoxIcon.Error); 42 } 43 finally 44 { 45 dbHelper.CloseConnection(); 46 } 47 }
1 /// <summary> 2 /// 显示当前播放的歌曲名字 3 /// </summary> 4 public void ShowPlayingSongName() 5 { 6 this.lblPlayingSong.Text = PlayList.PlayingSongName(); 7 this.lblNextSong.Text = PlayList.NextSongName(); 8 }
- 同一窗体显示不同界面
如果在一个窗体中显示不同的界面呢??
我们可以转换一下思路,所谓界面不同就是容器不同
解决方案:通过控制Form窗体中ListView控件的显示和隐藏来实现多界面窗体
歌星点歌
- 点击第一个LIstView,弹出第二个ListView解析:1.隐藏第一个ListView,显示第二个ListView
1 // 点击后,显示歌手类别 2 private void lvOrder_Click(object sender, EventArgs e) 3 { 4 if (lvOrder.SelectedItems[0] != null) 5 { 6 // 隐藏歌手性别,显示歌手类别 7 pnlSingerSex.Visible = false; 8 pnlSingerType.Location = pnlSingerSex.Location; 9 pnlSingerType.Dock = DockStyle.Fill; 10 pnlSingerType.Visible = true; 11 this.singerSex = Convert.ToString(lvOrder.SelectedItems[0].Tag); // 记录选择的性别 12 } 13 14 // 读取歌手类别 15 DBHelper dbHelper = new DBHelper(); 16 string sql = "select * from singer_type"; 17 try 18 { 19 // 查询数据库 20 SqlCommand command = new SqlCommand(sql, dbHelper.Connection); 21 dbHelper.OpenConnection();//相当于con.open 22 SqlDataReader reader = command.ExecuteReader(); 23 24 // 循环将类别读取出来添加到ListView中 25 lvSingerType.Items.Clear(); 26 int i = 0; 27 while (reader.Read()) 28 { 29 ListViewItem item = new ListViewItem(); 30 item.Text = Convert.ToString(reader["singertype_name"]); 31 item.Tag = Convert.ToInt32(reader["singertype_id"]); 32 item.ImageIndex = i; 33 lvSingerType.Items.Add(item); 34 i++; 35 } 36 reader.Close(); 37 } 38 catch (Exception ex) 39 { 40 Console.WriteLine(ex.Message); 41 MessageBox.Show("错误!"); 42 43 } 44 finally 45 { 46 dbHelper.CloseConnection(); 47 } 48 }
- 需要将【男歌手】汉字传递到第二个ListView上
- 显示5个国家的信息(包括文本和图片)
- 需要将【男歌手】汉字传递到第二个ListView上
- .显示5个国家的信息(包括文本和图片)点击第二个ListVIew,填出第三个ListView
// 点击类别后,显示对应类别下的歌手列表 private void lvSingerType_Click(object sender, EventArgs e) { // 隐藏歌手类别,显示歌手列表 pnlSingerType.Visible = false; pnlSingerList.Location = pnlSingerSex.Location; pnlSingerList.Dock = DockStyle.Fill; pnlSingerList.Visible = true; this.singerTypeId = Convert.ToInt32(lvSingerType.SelectedItems[0].Tag); // 保存选中的类别编号 // 读取数据库,读出歌手信息 DBHelper dbHelper = new DBHelper(); StringBuilder sql = new StringBuilder(); sql.AppendFormat("select singer_id,singer_name,singer_photo_url from singer_info where singertype_id={0} and singer_gender=‘{1}‘", this.singerTypeId,this.singerSex); try { SqlCommand command = new SqlCommand(sql.ToString(),dbHelper.Connection); dbHelper.OpenConnection(); SqlDataReader reader = command.ExecuteReader(); int imageIndex = 0; // 代表歌手头像的索引 ilSinger.Images.Clear(); // 循环读出歌手信息添加到窗体中显示 lvSinger.Items.Clear(); while (reader.Read()) { // 将歌手头像放在ImageList控件中 string photoURL = KTVUtil.singerPhotoPath + "\\" + Convert.ToString(reader["singer_photo_url"]); ilSinger.Images.Add(Image.FromFile(photoURL)); // 将歌手添加到ListView中 ListViewItem item = new ListViewItem(); item.Text = Convert.ToString(reader["singer_name"]); item.Tag = Convert.ToString(reader["singer_id"]); item.ImageIndex = imageIndex; lvSinger.Items.Add(item); imageIndex++; } reader.Close(); } catch (Exception ex) { Console.WriteLine(ex.Message); MessageBox.Show("错误!"); } finally { dbHelper.CloseConnection(); } }
- 第三个ListView出来后,点击其中的一个歌手,弹出该歌手演唱的所有歌曲
-
1 // 点击歌手姓名,打开歌曲列表窗口 2 private void lvSinger_Click(object sender, EventArgs e) 3 { 4 // 读取数据库,读出该歌手的所有歌曲 5 DBHelper dbHelper = new DBHelper(); 6 StringBuilder sb = new StringBuilder(); 7 sb.AppendFormat("select song_id,song_name, singer_name=‘{0}‘,song_url from song_info where singer_id={1}", 8 lvSinger.SelectedItems[0].Text, Convert.ToInt32(lvSinger.SelectedItems[0].Tag)); 9 10 FrmSongList songList = new FrmSongList(); 11 songList.Sql = sb.ToString(); 12 songList.Previous = PrevioisForm.Singer; // 指定返回的窗体是按歌手点歌 13 songList.Show(); 14 this.Close(); 15 }
1. 我们都知道ListView绑定首列的数据是通过
1 ListViewItem lvitem = new ListViewItem(stuno); 2 显示地区图片的代码: SqlDataReader dr = command.ExecuteReader(); 3 4 5 6 // 循环将类别读取出来添加到ListView中 7 8 lvlisttwo.Items.Clear(); 9 10 int i = 0; 11 12 while (dr.Read()) 13 14 { 15 16 ListViewItem item = new ListViewItem(); 17 18 item.Text = Convert.ToString(dr["singertype_name"]); 19 20 item.Tag = Convert.ToInt32(dr["singertype_id"]); 21 22 item.ImageIndex = i; 23 24 lvlisttwo.Items.Add(item); 25 26 i++; 27 28 } 29 30 dr.Close();
详细分析:
显示歌手的图片的代码
1 SqlDataReader dr = cmd.ExecuteReader(); 2 3 int imageIndex = 0; // 代表歌手头像的索引 4 5 imglistthree.Images.Clear(); 8 9 // 循环读出歌手信息添加到窗体中显示 10 11 lvlistthree.Items.Clear(); 12 13 while (dr.Read()) 14 15 { 16 17 // 将歌手头像放在ImageList控件中 18 19 string photoURL = KTVUtil.singerPhotoPath + "\\" + Convert.ToString(dr["singer_photo_url"]); 20 21 imglistthree.Images.Add(Image.FromFile(photoURL)); 24 25 // 将歌手添加到ListView中 26 27 ListViewItem item = new ListViewItem(); 28 29 item.Text = Convert.ToString(dr["singer_name"]); 30 31 item.Tag = Convert.ToString(dr["singer_id"]); 32 33 item.ImageIndex = imageIndex; 34 35 lvlistthree.Items.Add(item); 36 37 38 39 imageIndex++; 40 41 } 42 43 dr.Close(); 44 45 }
10 .ListView控件首列不能居中问题
- 我也没找到解决方法,能做的,也许就是把第一列宽度设为 0,不用第一列,从第二列开始用。此时 ListView1.Items[i].Text 也不能用了,因为它对应的是 ListView1[i].SubItems[0].Text。
- 设置ToolStrip对应项图片的大小,通过ImageScalingSize来设置。
- 04.Panel不能实现同一窗体不同界面。
17. 实现播放歌曲功能
01.点击某歌曲后,将选择的歌曲添加到已点列表
02.在已点列表中放入一个Timer控件,实时检测每首歌曲的状态
03.在播放窗口中放入一个Timer控件,实时检测需要播放的歌曲
1 private void PlayForm_Load(object sender, EventArgs e) 2 { 3 this.PlaySong(); 4 this.timer1.Start(); 5 } 6 7 /// <summary> 8 /// 播放歌曲 9 /// </summary> 10 private void PlaySong() 11 { 12 this.song = PlayList.GetPlayingSong(); // 获取当前要播放的歌曲 13 if (song != null) 14 { 15 this.song.SetSongPlayed(); // 将当前歌曲播放状态设为已播放 16 this.wmpSong.URL = KTVUtil.songPath + "\\" + this.song.SongURL; // 得到当前播放歌曲的路径 17 } 18 } 19 20 private void timer1_Tick(object sender, EventArgs e) 21 { 22 if(this.song == null) 23 { 24 this.PlaySong(); 25 } 26 if (this.wmpSong.playState == WMPLib.WMPPlayState.wmppsStopped) 27 { 28 this.song = null; // 将歌曲设为空 29 PlayList.MoveOn(); 30 } 31 // 切歌 32 if (this.song != null && this.song.PlayState == SongPlayState.cut) 33 { 34 this.wmpSong.URL = ""; 35 this.song = null; 36 } 37 }
实现播放列表操作:
1.KTVUtil 类:
1 class KTVUtil 2 3 { 4 5 public static string singerPhotoPath = ""; // 歌手照片路径 6 7 public static string songPath = ""; // 歌曲路径 8 9 }
2.编写歌曲类(Song.cs)
1 代码例子:enum SongPlayState 2 3 { 4 5 unplayed, played, again, cut 6 7 } 8 9 // 歌曲类 10 11 class Song 12 13 { 14 15 //歌曲名称 16 17 public string SongName 18 19 { 20 21 get { return songName; } 22 23 set { songName = value; } 24 25 } 26 27 //歌曲存放路径 28 29 public string SongURL 30 31 { 32 33 get { return songURL; } 34 35 set { songURL = value; } 36 37 } 38 39 // 歌曲播放状态 40 41 internal SongPlayState PlayState 42 43 { 44 45 get { return playState; } 46 47 set { playState = value; } 48 49 } 50 51 private string songName; 52 53 private string songURL; 54 55 // 歌曲播放状态,默认为未播放状态 56 57 private SongPlayState playState = SongPlayState.unplayed; 58 59 //将歌曲状态改为已播放 60 61 public void SetSongPlayed() 62 63 { 64 65 this.playState = SongPlayState.played; 66 67 } 68 69 // 将歌曲状态改为再拨放一次 70 71 public void SetPlayAgain() 72 73 { 74 75 this.playState = SongPlayState.again; 76 77 } 78 79 // 将歌曲状态改为切歌 80 81 public void SetSongCut() 82 83 { 84 85 this.playState = SongPlayState.cut;
3.编写播放列表类(PlayList.cs),提供播放列表的各种方法
代码例子:// 播放列表管理
1 2 class PlayList 3 4 { 5 6 // 歌曲播放列表数组 7 8 private static Song[] songList = new Song[50]; 9 10 // 当前播放的歌曲在数组中的索引 11 12 private static int songIndex = 0; 13 14 // 播放列表数组 15 16 public static Song[] SongList 17 18 { 19 20 get { return PlayList.songList; } 21 22 } 23 24 //当前播放歌曲的索引 25 26 public static int SongIndex 27 28 { 29 30 get { return PlayList.songIndex; } 31 32 } 33 34 // 当前播放的歌曲名称 35 36 public static string PlayingSongName() 37 38 { 39 40 string songName = ""; // 歌曲名称 41 42 if (SongList[SongIndex] != null) 43 44 { 45 46 songName = SongList[SongIndex].SongName; 47 48 } 49 50 return songName; 51 52 } 53 54 //获取当前播放的歌曲 55 56 public static Song GetPlayingSong() 57 58 { 59 60 if (SongList[songIndex] != null) 61 62 { 63 return SongList[songIndex]; 64 } 65 66 else 67 68 { 69 return null; 70 71 } 72 73 } 74 75 //下一首要播放的歌曲名称 76 77 public static string NextSongName() 78 79 { 80 81 string songName = ""; // 歌曲名称 82 83 if (SongList[SongIndex + 1] != null) 84 85 { 86 songName = SongList[SongIndex + 1].SongName; 87 } 88 return songName; 89 90 } 91 92 93 94 // 点播,及添加播放,一首歌曲 95 96 public static bool AddSong(Song song) 97 98 { 99 100 //默认为没有添加播放歌曲 101 102 bool success = false; 103 104 //for遍历Song[], 105 106 for (int i = 0; i < SongList.Length; i++) 107 { 108 if (SongList[i] == null) 109 110 { 111 112 SongList[i] = song; 113 114 // Console.WriteLine(song.SongName); 115 116 //返回要播放的歌曲, 117 118 success = true; 119 120 break; 121 } 122 } 123 return success; 124 125 } 126 // 切歌 要切歌曲的编号,如果是切当前播放的歌曲传入-1 127 128 public static void CutSong(int index) 129 130 { 131 132 int i; // 循环变量,代表切歌的位置 133 134 if (index == -1) 135 136 { 137 i = SongIndex; 138 } 139 else 140 { 141 i = index; // 从切歌的位置开始,将歌曲逐个向前移一个位置 142 } 143 SongList[i].SetSongCut(); 144 while (SongList[i] != null) 145 { 146 SongList[i] = SongList[i + 1]; 147 i++; 148 // 如果到达数组最后一个元素,就将最后一个元素指向空 149 if (i == SongList.Length) 150 { 151 SongList[i] = null; 152 } 153 154 } 155 156 } 157 // 重放当前歌曲 158 public static void PlayAgain() 159 { 160 if (SongList[songIndex] != null) 161 { 162 SongList[songIndex].SetPlayAgain(); 163 } 164 } 165 // 播放下一首 166 public static void MoveOn() 167 168 KTV点歌系统