c# 类似于QQ表情弹出框功能的二种实现方法以下是做项目时实现的二种类似于QQ表情弹出框功能的实现方法,方法一采用DataGridView实现,方法二通过ToolStripDropDown实现。
一先贴出实现效果。 方法一 DataGridView效果
方法二ToolStripDropDown效果
二 二种方法实现的对比: 方法一 效果类似于QQ,鼠标放在上面时,可以看到显示的效果,但加裁速度有些慢。 方法二的效果类似于MSN,加裁速度比较快,鼠标放在上面时能显示图片的ToolTipText。
三 实现源代码 (1) 方法一。该方法是把图片的位置值存放到DataGridVeiw各个单元格中,在DataGridView的dataGridView1_CellFormatting。这里使用到了e.Value中的Object类型。由于 e.Value为Object类型,所以可以直接显示图片。
private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{ //如果值不为空 if(e.Value!=null) { string path = e.Value.ToString();//得到路径值 e.Value = GetImage(path);//根据路径值获取图片。因为e.Value是Object,图片文件可以直接显示 } else { e.Value = Properties.Resources.snow;//默读背景图片 } }
在GetImage方法中,读取图片时采用File.OpenRead(path) 方法,该方法可以防止图片文件正在被另一程序访问或只读或未释放。如果采用Image.FormFile()则可能会出现异常。
/// <summary>
/// 加裁图片 /// </summary> /// <param name="path"></param> /// <returns></returns> private object GetImage(string path) { try { FileStream fs = File.OpenRead(path);//调用该方法,可以防止文件正在防问或只读或被锁定状态 int filelength = 0; filelength = (int)fs.Length; //获得文件长度 Byte[] image = new Byte[filelength]; //建立一个字节数组 fs.Read(image, 0, filelength); //按字节流读取 System.Drawing.Image result = System.Drawing.Image.FromStream(fs); fs.Close(); return result; } catch (Exception) { } return null; }
当鼠标通过图片时用PictureBox显示图片
DataGridViewCellStyle sty = new DataGridViewCellStyle();
sty.BackColor = Color.Snow; object path = dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value; foreach (DataGridViewRow row in dataGridView1.Rows) { foreach (DataGridViewCell cell in row.Cells) { cell.Style = sty; } } DataGridViewCellStyle sty2 = new DataGridViewCellStyle(); sty2.BackColor = Color.Blue; if (path != null) { dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Style = sty2; Image img = Bitmap.FromFile(path.ToString()); if (e.RowIndex < 4 && e.ColumnIndex < 4) { pictureBox1.Visible = false; pictureBox31.Visible = true; } else { pictureBox1.Visible = true; pictureBox31.Visible = false; } pictureBox1.Image = img; pictureBox31.Image = img; } else { pictureBox1.Image = Properties.Resources.snow; pictureBox31.Image = Properties.Resources.snow; }
以上就是方法一的主要实现过程,该方法有一个不好的地方就是速度比较慢,因为dataGridView1_CellFormatting事件发生太频繁,导致一直在加裁图片。 以下为完整代码:
代码
1 private string facepath = string.Empty;
2 public static string ImageName = string.Empty; 3 4 public EventHandler FaceCellClick; 5 public frmFace( string path) 6 { 7 InitializeComponent(); 8 if(!path.EndsWith("\\")) 9 { 10 path = path + "\\"; 11 } 12 facepath = path; 13 GetData(); 14 pictureBox1.Visible = false; 15 pictureBox31.Visible = false; 16 } 17 /// <summary> 18 /// 加裁图片并添枝加叶到DataGridViewa 19 /// </summary> 20 private void GetData() 21 { 22 string[] files = Directory.GetFiles(facepath, "*.gif");//获取图片 23 int colomn = 0; 24 int row = 0; 25 DataGridViewRow dgvRow; 26 dataGridView1.Rows.Add(new DataGridViewRow()); 27 foreach (string s in files) 28 { 29 if (!s.EndsWith("snow.gif"))//排除snow.gif 30 { 31 dataGridView1.Rows[row].Cells[colomn].Value = s; 32 colomn++; 33 if (colomn == 10) 34 { 35 //增加到DataGridView 36 dataGridView1.Rows.Add(new DataGridViewRow()); 37 row++; 38 colomn = 0; 39 } 40 } 41 } 42 } 43 /// <summary> 44 /// 单元格格式化 45 /// </summary> 46 /// <param name="sender"></param> 47 /// <param name="e"></param> 48 private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) 49 { 50 if(e.Value!=null) 51 { 52 string path = e.Value.ToString(); 53 e.Value = GetImage(path); 54 } 55 else 56 { 57 e.Value = Properties.Resources.snow; 58 } 59 } 60 /// <summary> 61 /// 得到图片 62 /// </summary> 63 /// <param name="path"></param> 64 /// <returns></returns> 65 private object GetImage(string path) 66 { 67 try 68 { 69 FileStream fs = File.OpenRead(path); 70 int filelength = 0; 71 filelength = (int)fs.Length; //获得文件长度 72 Byte[] image = new Byte[filelength]; //建立一个字节数组 73 fs.Read(image, 0, filelength); //按字节流读取 74 System.Drawing.Image result = System.Drawing.Image.FromStream(fs); 75 fs.Close(); 76 return result; 77 78 } 79 catch (Exception) 80 { 81 } 82 return null; 83 84 } 85 /// <summary> 86 /// 单元格点击事件 87 /// </summary> 88 /// <param name="sender"></param> 89 /// <param name="e"></param> 90 private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e) 91 { 92 if (FaceCellClick != null) 93 { 94 try 95 { 96 object path = dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value; 97 if (path != null) 98 { 99 ImageName = path.ToString().Substring(path.ToString().LastIndexOf("\\")); 100 } 101 else 102 { 103 ImageName = string.Empty; 104 } 105 } 106 catch 107 { 108 ImageName = string.Empty; 109 } 110 } 111 this.DialogResult = System.Windows.Forms.DialogResult.OK; 112 } 113 /// <summary> 114 /// 鼠标通过时显示效果 115 /// </summary> 116 /// <param name="sender"></param> 117 /// <param name="e"></param> 118 private void dataGridView1_CellMouseMove(object sender, DataGridViewCellMouseEventArgs e) 119 { 120 DataGridViewCellStyle sty = new DataGridViewCellStyle(); 121 sty.BackColor = Color.Snow; 122 123 object path = dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value; 124 foreach (DataGridViewRow row in dataGridView1.Rows) 125 { 126 foreach (DataGridViewCell cell in row.Cells) 127 { 128 cell.Style = sty; 129 } 130 } 131 DataGridViewCellStyle sty2 = new DataGridViewCellStyle(); 132 sty2.BackColor = Color.Blue; 133 if (path != null) 134 { 135 dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Style = sty2; 136 Image img = Bitmap.FromFile(path.ToString()); 137 if (e.RowIndex < 4 && e.ColumnIndex < 4) 138 { 139 pictureBox1.Visible = false; 140 pictureBox31.Visible = true; 141 } 142 else 143 { 144 pictureBox1.Visible = true; 145 pictureBox31.Visible = false; 146 } 147 148 pictureBox1.Image = img; 149 pictureBox31.Image = img; 150 } 151 else 152 { 153 pictureBox1.Image = Properties.Resources.snow; 154 pictureBox31.Image = Properties.Resources.snow; 155 } 156 }
方法二 通过ToolStripDropDown(http://msdn.microsoft.com/zh-cn/library/system.windows.forms.toolstripdropdown_methods.aspx)实现. 2 Flow 如果 LayoutStyle 属性设置为 Flow 或 Table,将不会显示大小调整手柄。 这里设置emotionDropDown.LayoutStyle = ToolStripLayoutStyle.Table;//设置布局.
主要实现代码为 private ToolStripDropDown emotionDropDown = new ToolStripDropDown();
代码
1 private void UCChatForm_Load(object sender, EventArgs e)
2 { 3 lock (richtxtChat.Emotions) 4 { 5 richtxtChat.Emotions[":)"] = Properties.Resources.face01;//微笑face01 6 richtxtChat.Emotions[":D"] = Properties.Resources.face02;//大笑face02 7 richtxtChat.Emotions[":-o"] = Properties.Resources.face03;//惊讶face03 8 richtxtChat.Emotions[":P"] = Properties.Resources.face04;//吐舌笑脸face04 9 richtxtChat.Emotions["(H)"] = Properties.Resources.face05;//热烈的笑脸face05 10 richtxtChat.Emotions[":@"] = Properties.Resources.face06;//生气face06 11 richtxtChat.Emotions[":S"] = Properties.Resources.face07;//困惑face07 12 richtxtChat.Emotions[":$"] = Properties.Resources.face08;//尴尬face08 13 richtxtChat.Emotions[":("] = Properties.Resources.face09;//悲伤face09 14 richtxtChat.Emotions[":'("] = Properties.Resources.face10;//哭泣的脸face10 15 richtxtChat.Emotions[":|"] = Properties.Resources.face11;//失望face11 16 richtxtChat.Emotions["(A)"] = Properties.Resources.face12;//天使face12 17 richtxtChat.Emotions["8o|"] = Properties.Resources.face13;//咬牙切齿face13 18 richtxtChat.Emotions["8-|"] = Properties.Resources.face14;//书呆子face14 19 richtxtChat.Emotions["+o("] = Properties.Resources.face15;//生病face15 20 richtxtChat.Emotions["<:o)"] = Properties.Resources.face16;//聚会笑脸face16 21 richtxtChat.Emotions["|-)"] = Properties.Resources.face17;//困了face17 22 richtxtChat.Emotions["*-)"] = Properties.Resources.face18;//正在思考face18 23 richtxtChat.Emotions[":-*"] = Properties.Resources.face19;//悄悄话face19 24 richtxtChat.Emotions[":-#"] = Properties.Resources.face20;//保守秘密face20 25 richtxtChat.Emotions["^o)"] = Properties.Resources.face21;//讽刺face21 26 richtxtChat.Emotions["8-)"] = Properties.Resources.face22;//转动眼睛face22 27 richtxtChat.Emotions["(L)"] = Properties.Resources.face23;//红心face23 28 richtxtChat.Emotions["(U)"] = Properties.Resources.face24;//破碎的心face24 29 richtxtChat.Emotions["(M)"] = Properties.Resources.face25;//Messenger face25 30 richtxtChat.Emotions["(@)"] = Properties.Resources.face26;//猫脸face26 31 richtxtChat.Emotions["(&)"] = Properties.Resources.face27;//狗脸face27 32 richtxtChat.Emotions["(sn)"] = Properties.Resources.face28;//蜗牛face28 33 richtxtChat.Emotions["(bah)"] = Properties.Resources.face29;//黑羊face29 34 richtxtChat.Emotions["(S)"] = Properties.Resources.face30;//沉睡的弯月face30 35 richtxtChat.Emotions["(*)"] = Properties.Resources.face31;//星星face31 36 richtxtChat.Emotions["(#)"] = Properties.Resources.face32;//太阳face32 37 richtxtChat.Emotions["(R)"] = Properties.Resources.face33;//握手face33 38 richtxtChat.Emotions["({)"] = Properties.Resources.face34;//左侧拥抱face34 39 richtxtChat.Emotions["(})"] = Properties.Resources.face35;//右侧拥抱face35 40 richtxtChat.Emotions["(K)"] = Properties.Resources.face36;//红唇face36 41 richtxtChat.Emotions["(F)"] = Properties.Resources.face37;//红玫瑰face37 42 richtxtChat.Emotions["(W)"] = Properties.Resources.face38;//凋谢的玫瑰face38 43 richtxtChat.Emotions["(O)"] = Properties.Resources.face39;//时钟face39 44 richtxtChat.Emotions["(Y)"] = Properties.Resources.face40;//太棒了face40 45 richtxtChat.Emotions["(N)"] = Properties.Resources.face41;//太差了face41 46 richtxtChat.Emotions["(C)"] = Properties.Resources.face42;//咖啡face42 47 richtxtChat.Emotions["(E)"] = Properties.Resources.face43;//电子邮件face43 48 richtxtChat.Emotions["(li)"] = Properties.Resources.face44;//闪电face44 49 richtxtChat.Emotions["(I)"] = Properties.Resources.face45;//灯泡face45 50 richtxtChat.Emotions["(T)"] = Properties.Resources.face46;//电话听筒face46 51 richtxtChat.Emotions["(8)"] = Properties.Resources.face47;//音符face47 52 c.Emotions["(mp)"] = Properties.Resources.face48;//移动电话face48 53 richtxtChat.Emotions["(^)"] = Properties.Resources.face49;//生日蛋糕face49 54 richtxtChat.Emotions["(G)"] = Properties.Resources.face50;//礼品盒face50 55 } 56 57 58 59 emotionDropDown.ImageScalingSize = new Size(15, 15);//图片大小 60 emotionDropDown.LayoutStyle = ToolStripLayoutStyle.Table;//设置布局 61 foreach (string str in richtxtChat.Emotions.Keys) 62 { 63 emotionDropDown.Items.Add(null, richtxtChat.Emotions[str], emotion_Click).ToolTipText = GetToolTipText(str); 64 } 65 ((TableLayoutSettings)emotionDropDown.LayoutSettings).ColumnCount = 13;//设置每行显示数目 66 }
其中richtxtChat为RtfRichTextBox。在这里设置每行显示13个。 显示注释的方法GetToolTipText(str):
代码
/// <summary>
/// 显示表情注释 /// </summary> /// <param name="str">图释KEY</param> /// <returns></returns> private string GetToolTipText(string str) { switch (str) { case ":)": str = "微笑 " + str; break; case ":D": str = "大笑 " + str; break; case ":-o": str = "惊讶 " + str; break; case ":P": str = "吐舌笑脸 " + str; break; case "(H)": str = "热烈的笑脸 " + str; break; case ":@": str = "生气 " + str; break; case ":S": str = "困惑 " + str; break; case ":$": str = "尴尬 " + str; break; case ":(": str = "悲伤 " + str; break; case ":'(": str = "哭泣 " + str; break; case ":|": str = "失望 " + str; break; case "(A)": str = "天使 " + str; break; case "8o|": str = "咬牙切齿 " + str; break; case "8-|": str = "书呆子 " + str; break; case "+o(": str = "生病 " + str; break; case "<:o)": str = "聚会笑脸 " + str; break; case "|-)": str = "困了 " + str; break; case "*-)": str = "正在思考 " + str; break; case ":-*": str = "悄悄话 " + str; break; case ":-#": str = "保守秘密 " + str; break; case "^o)": str = "讽刺 " + str; break; case "8-)": str = "转动眼睛 " + str; break; case "(L)": str = "红心 " + str; break; case "(U)": str = "破碎的心 " + str; break; case "(M)": str = "Messenger " + str; break; case "(@)": str = "猫脸 " + str; break; case "(&)": str = "狗脸 " + str; break; case "(sn)": str = "蜗牛 " + str; break; case "(bah)": str = "黑羊 " + str; break; case "(S)": str = "沉睡的弯月 " + str; break; case "(*)": str = "星星 " + str; break; case "(#)": str = "太阳 " + str; break; case "(R)": str = "握手 " + str; break; case "({)": str = "左侧拥抱 " + str; break; case "(})": str = "右侧拥抱 " + str; break; case "(K)": str = "红唇 " + str; break; case "(F)": str = "红玫瑰 " + str; break; case "(W)": str = "凋谢的玫瑰 " + str; break; case "(O)": str = "时钟 " + str; break; case "(Y)": str = "太棒了 " + str; break; case "(N)": str = "太差了 " + str; break; case "(C))": str = "咖啡 " + str; break; case "(E)": str = "电子邮件 " + str; break; case "(li)": str = "闪电 " + str; break; case "(I)": str = "灯泡 " + str; break; case "(T)": str = "电话听筒 " + str; break; case "(8)": str = "音符 " + str; break; case "(mp)": str = "移动电话 " + str; break; case "(^)": str = "生日蛋糕 " + str; break; case "(G)": str = "礼品盒 " + str; break; default: break; } return str; }
代码
/// <summary>
/// 发送表情 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void emotion_Click(object sender, EventArgs e) { ToolStripItem item = (ToolStripItem)sender; if(item==null) { return; } string text = item.ToolTipText; if (text.Split(' ').Length > 1) { text = text.Split(' ')[1]; } richtxtSend.AppendText(text);//发送Text richtxtSend.Focus(); SendButton.Enabled = true; } |
|