经过一个多星期的KTV项目总与写完了,
先进入主界面吧:
主界面有五个点歌功能,歌星点歌,拼音点歌,类型选择,金榜排行,字数点歌
先看看歌星点歌吧:
进入歌星点歌胡会出现如下界面
通过点击男,女,组合,会进入下一级菜单
进入到地区分类界面
如图:
通过第一个界面进入到对应的地区界面
代码如下:
1 public void ShowSingerDiQu() 2 { 3 if (listView1.SelectedItems[0]!=null) 4 { 5 listView1.Visible = false; 6 listView2.Visible = true; 7 listView2.Location = listView1.Location; 8 9 this.SingerType = Convert.ToString(listView1.SelectedItems[0].Tag); 10 } 11 string sql = "select singertype_name,singertype_id from singer_type"; 12 SqlCommand cmd = new SqlCommand(sql,db.Conection); 13 SqlDataReader sdr; 14 try 15 { 16 db.OpenConnection(); 17 sdr = cmd.ExecuteReader(); 18 listView1.Items.Clear(); 19 if (sdr.HasRows) 20 { 21 int result = 0; 22 while (sdr.Read()) 23 { 24 ListViewItem lvitem = new ListViewItem(); 25 string typename = Convert.ToString(sdr["singertype_name"]); 26 int typeid = Convert.ToInt32(sdr["singertype_id"]); 27 lvitem.Text = typename; 28 lvitem.Tag = typeid; 29 lvitem.ImageIndex = result; 30 listView2.Items.Add(lvitem); 31 result++; 32 } 33 sdr.Close(); 34 } 35 } 36 catch (Exception ex) 37 { 38 MessageBox.Show("第二个系统报错" + ex.Message); 39 } 40 finally 41 { 42 db.CloseConnection(); 43 } 44 }
通过地区界面会进入到具体的人名下:
人名下会有歌星的歌曲
通过读取对应的地区得到对应的歌手
1 /// <summary> 2 /// 读取对应地区的歌手名称 3 /// </summary> 4 public void ShowSingerName() 5 { 6 if (listView2.SelectedItems[0]!=null) 7 { 8 listView2.Visible = false; 9 lvName.Visible = true; 10 lvName.Location = listView1.Location; 11 SingerId = Convert.ToInt32(listView2.SelectedItems[0].Tag); 12 StringBuilder sb = new StringBuilder(); 13 string sum = SingerType; 14 if (sum!="组合") 15 { 16 sum = SingerType == "女歌手" ? "男" : "女"; 17 } 18 string sql = string.Format("select singer_name,singer_photo_url,singer_id from singer_info where singertype_id='{0}' and singer_sex='{1}'", SingerId,sum); 19 SqlCommand cmd = new SqlCommand(sql, db.Conection); 20 try 21 { 22 db.OpenConnection(); 23 SqlDataReader read = cmd.ExecuteReader(); 24 25 //歌手头像索引 26 int imageindex = 0; 27 //清空图片集合 28 imageName.Images.Clear(); 29 //清空listview列表集合 30 lvName.Items.Clear(); 31 if (read.HasRows) 32 { 33 while (read.Read()) 34 { 35 //图片的地址 36 string path = KtvUtil.FilePath + @"\" + Convert.ToString(read["singer_photo_url"]); 37 //图片路径装载到imagelist 38 imageName.Images.Add(Image.FromFile(path)); 39 //将类型装载到集合中去 40 ListViewItem lvitem = new ListViewItem(); 41 string typename = Convert.ToString(read["singer_name"]); 42 int typeid = Convert.ToInt32(read["singer_id"]); 43 lvitem.Text = typename; 44 lvitem.Tag = typeid; 45 lvitem.ImageIndex = imageindex; 46 lvName.Items.Add(lvitem); 47 imageindex++; 48 } 49 read.Close(); 50 } 51 } 52 catch (Exception ex) 53 { 54 MessageBox.Show("第三个系统报错!" + ex.Message); 55 } 56 finally 57 { 58 db.CloseConnection(); 59 } 60 } 61 62 }
通过歌手界面进入到对应歌手的歌曲:
代码如下:
1 public void ShowList() 2 { 3 //定义一个StringBuilder对象 4 StringBuilder sb = new StringBuilder(); 5 //sql语句 6 string sql = string.Format("select song_id,song_name,singer_name='{0}',song_url from song_info where singer_id={1}",lvName.SelectedItems[0].Text,Convert.ToInt32(lvName.SelectedItems[0].Tag)); 7 //定义歌曲列表窗体的对象 8 FrmSongList sl=new FrmSongList(); 9 //把sql语句传到第三个窗体上 10 sl.Sql=sql; 11 sl.ShowDialog(); 12 this.Close(); 13 }
歌手点歌是用同一个窗体用listview实现了三层筛选进入到歌曲,进行点歌,
当点击歌曲的时候歌曲会自动播放并添加到已播放歌曲列表中,
代码如下:
在palylist类中
先声明一个数组用来存放歌曲,在写一个添加歌曲的方法
1 //定义一个集合存放歌曲 2 public static SongList[] song=new SongList[50]; 3 //定义一个数组索引 4 public static int selectindex=0; 5 /// <summary> 6 /// 添加歌曲 7 /// </summary> 8 /// <param name="sl"></param> 9 /// <returns></returns> 10 public static void AddSong(SongList sl) 11 { 12 //记录歌曲是否添加成功 13 for (int i = 0; i < song.Length; i++) 14 { 15 if (song[i]==null) 16 { 17 //把歌曲类里的歌曲添加到数组中 18 song[i] = sl; 19 //添加成功 20 break; 21 } 22 } 23 24 }
1 /// <summary> 2 /// 播放歌曲方法 3 /// </summary> 4 /// <returns></returns> 5 public static SongList GetSong() 6 { 7 if (song[selectindex]!=null) 8 { 9 return song[selectindex]; 10 } 11 else 12 { 13 return null; 14 } 15 }
在songlist类中要有如下代码:
1 public enum PalySongState 2 { 3 //未播放 , 播放, 重播,切歌 4 unplayed,played,again,cut 5 } 6 /// <summary> 7 /// 歌曲播放类 8 /// </summary> 9 public class SongList 10 { 11 //歌曲名称 12 private string SongName; 13 //歌曲路径 14 private string SongUl; 15 //歌曲状态 16 private string SongState; 17 18 public string SongState1 19 { 20 get { return SongState; } 21 set { SongState = value; } 22 } 23 24 public string SongUl1 25 { 26 get { return SongUl; } 27 set { SongUl = value; } 28 } 29 30 public string SongName1 31 { 32 get { return SongName; } 33 set { SongName = value; } 34 } 35 36 //把当前的播放状态设置为未播放状态 37 private PalySongState playSong = PalySongState.unplayed; 38 39 public PalySongState PlaySong 40 { 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 }
再把歌曲添加到数组中去:
代码如下:
在dataGridView的CellContentClick的事件写代码;
1 private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e) 2 { 3 if (this.dataGridView1.SelectedRows[0] != null) 4 { 5 SongList song = new SongList(); 6 //歌曲名称 7 song.SongName1 = this.dataGridView1.SelectedRows[0].Cells[0].Value.ToString(); 8 //歌曲路径 9 song.SongUl1 = this.dataGridView1.SelectedRows[0].Cells[2].Value.ToString(); 10 MessageBox.Show(song.SongUl1); 11 PalyList.AddSong(song); 12 13 } 14 }
在已播界面的lode事件中写如下代码用来控制播放类型
1 private void FrmOrderedSongList_Load(object sender, EventArgs e) 2 { 3 //遍历播放类里面的数组 4 foreach (SongList item in PalyList.song) 5 { 6 7 if (item!=null) 8 { 9 ListViewItem lvitem = new ListViewItem(item.SongName1); 10 string type = item.PlaySong == PalySongState.unplayed ? "未播放" : "已播放"; 11 lvitem.SubItems.Add(type); 12 this.listView1.Items.Add(lvitem); 13 } 14 15 } 16 }
在通过ktvUtil类中写两个静态的字段,一个是图片路径,一个是歌曲路径
1 //定义一个静态变量存放图片路径 2 public static string FilePath=""; 3 //定义一个静态变量存放歌曲的路径 4 public static string SongPath = "";
在主界面的lode事件中写图片和歌曲的路径
1 private void Form1_Load(object sender, EventArgs e) 2 { 3 //读取路径表中的图片路径放到filepath上 4 string sql = "select resource_path from resource_path where resource_id=1"; 5 SqlCommand cmd = new SqlCommand(sql,db.Conection); 6 db.OpenConnection(); 7 KtvUtil.FilePath = cmd.ExecuteScalar().ToString(); 8 db.CloseConnection(); 9 10 //读取歌曲的路径 11 string sql2 = "select resource_path from resource_path where resource_id=2"; 12 SqlCommand cmd2 = new SqlCommand(sql2, db.Conection); 13 db.OpenConnection(); 14 KtvUtil.SongPath = cmd2.ExecuteScalar().ToString(); 15 db.CloseConnection(); 16 17 }
然后进入 拼音点歌
代码如下:
1 /// <summary> 2 /// 绑定dgv数据 3 /// </summary> 4 public void ShowPinYin(string ab) 5 { 6 ab = textBox1.Text; 7 string sql = "select singer_info.singer_name,song_info.song_name,song_url from singer_info,song_info where singer_info.singer_id=song_info.singer_id"; 8 if (ab!=string.Empty) 9 { 10 sql = string.Format(sql+" and song_info.song_ab like '{0}%'",ab); 11 } 12 sda.SelectCommand = new SqlCommand(sql,db.Conection); 13 if (ds.Tables["songinfo"]!=null) 14 { 15 ds.Tables["songinfo"].Clear(); 16 } 17 sda.Fill(ds,"songinfo"); 18 DataTable table=ds.Tables["songinfo"]; 19 this.dataGridView1.DataSource = ds.Tables["songinfo"]; 20 //return; 21 22 }
1 /// <summary> 2 /// 查询按钮 3 /// </summary> 4 /// <param name="sender"></param> 5 /// <param name="e"></param> 6 private void button1_Click(object sender, EventArgs e) 7 { 8 if (this.textBox1!=null) 9 { 10 this.ShowPinYin(this.textBox1.Text); 11 } 12 else 13 { 14 MessageBox.Show("查询内容不可为空,请填写查询信息!","信息提示",MessageBoxButtons.OK,MessageBoxIcon.Information); 15 } 16 ShowPinYin(string.Empty); 17 }
类型选择:
如图:
代码如下:
1 public void FrmOrderBySongType_Load(object sender, EventArgs e) 2 { 3 4 int index = 0; 5 string sql = "select songtype_id,songtype_name,songtype_URL from song_type"; 6 SqlCommand cmd = new SqlCommand(sql, db.Conection); 7 try 8 { 9 db.OpenConnection(); 10 SqlDataReader reader = cmd.ExecuteReader(); 11 if (reader.HasRows) 12 { 13 while (reader.Read()) 14 { 15 string path = KtvUtil.FilePath +"\\"+ Convert.ToString(reader["songtype_URL"]); 16 imageList1.Images.Add(Image.FromFile(path)); 17 ListViewItem lvitem = new ListViewItem(); 18 string typename = Convert.ToString(reader["songtype_name"]); 19 int typeid = Convert.ToInt32(reader["songtype_id"]); 20 lvitem.Text = typename; 21 lvitem.Tag = typeid; 22 lvitem.ImageIndex = index; 23 this.listView1.Items.Add(lvitem); 24 index++; 25 26 } 27 } 28 reader.Close(); 29 } 30 catch (Exception ex) 31 { 32 MessageBox.Show("系统出错!"+ex.Message); 33 } 34 finally { 35 db.CloseConnection(); 36 } 37 this.dataGridView1.Visible = false; 38 }
通过歌曲类型进入到下一层
代码如下:
1 public void ShowDGV() 2 { 3 4 string sql = "SELECT song_name,singer_name FROM singer_info,song_info WHERE singer_info.singer_id=song_info.singer_id AND songtype_id={0}"; 5 sql = string.Format(sql + " AND songtype_id={0}", Convert.ToInt32(listView1.SelectedItems[0].Tag)); 6 sda.SelectCommand = new SqlCommand(sql, db.Conection); 7 if (ds.Tables["num"] != null) 8 { 9 ds.Tables["num"].Clear(); 10 } 11 sda.Fill(ds, "num"); 12 this.dataGridView1.DataSource = ds.Tables["num"]; 13 14 }
字数点歌:
如图
字数点歌用的是动态加载代码如下:
1 public void FrmOrderByWordCount_Load(object sender, EventArgs e) 2 { 3 for (int i = 1; i <= 2; i++) 4 { 5 for (int j = 1; j <= 6; j++) 6 { 7 Label lbl = new Label(); 8 lbl.Text = "第" + j + "个字"; 9 if (i ==2) 10 { 11 lbl.Text = "第" + (j+6) + "个字"; 12 } 13 //背景颜色 14 lbl.BackColor = Color.Red; 15 //字体大小 16 lbl.Size = new Size(55, 25); 17 //字体居中 18 lbl.TextAlign = ContentAlignment.MiddleCenter; 19 //点击事件 20 lbl.Click += lbl_Click; 21 //位置 22 lbl.Location = new Point(50 + 100 * i, 50 + 40 * j); 23 this.Controls.Add(lbl); 24 } 25 } 26 //隐藏dgv 27 this.dataGridView1.Visible = false; 28 }
显示出歌曲
1 int mains; 2 void lbl_Click(object sender, EventArgs e) 3 { 4 Label label = (Label)sender; 5 //文本 6 string main = label.Text; 7 //文本的长度 8 int sum = main.Length; 9 if (sum == 4) 10 { 11 mains = int.Parse(main.Substring(1, 1)); 12 } 13 else 14 { 15 mains = int.Parse(main.Substring(1,2)); 16 } 17 //MessageBox.Show(mains.ToString()); 18 //释放dgv 19 this.dataGridView1.Visible = true; 20 21 ShowDGV(); 22 23 } 24 public void ShowDGV() 25 { 26 if (ds.Tables["num"] != null) 27 { 28 ds.Tables["num"].Clear(); 29 } 30 string sql = "select song_info.song_name,singer_info.singer_name,song_info.song_url from song_info,singer_info where song_info.singer_id=singer_info.singer_id "; 31 sql = string.Format(sql + " and song_info.song_word_count={0}", mains.ToString()); 32 sda.SelectCommand = new SqlCommand(sql,db.Conection); 33 34 sda.Fill(ds,"num"); 35 this.dataGridView1.DataSource=ds.Tables["num"]; 36 37 }
主界面的下方有工具菜单
有播放,有切歌,
切歌代码如下:
1 /// <summary> 2 /// 切歌方法 3 /// </summary> 4 /// <param name="index"></param> 5 public static void CutSong(int index) 6 { 7 //歌曲的位置 8 int num; 9 if (index==-1) 10 { 11 num = selectindex; 12 } 13 else 14 { 15 num = index; 16 } 17 song[selectindex].CutState(); 18 while (song[num]!=null) 19 { 20 song[num] = song[num + 1]; 21 num++; 22 if (num==song.Length) 23 { 24 song[num] = null; 25 } 26 } 27 28 }
1 /// <summary> 2 /// 切歌 3 /// </summary> 4 /// <param name="sender"></param> 5 /// <param name="e"></param> 6 private void toolStripButton6_Click(object sender, EventArgs e) 7 { 8 if (MessageBox.Show("确定要切歌吗?", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) == DialogResult.OK) 9 { 10 PalyList.CutSong(-1); 11 } 12 }