以下是做项目时实现的二种类似于QQ表情弹出框功能的实现方法,方法一采用DataGridView实现,方法二通过ToolStripDropDown实现。
一先贴出实现效果。
方法一 DataGridView效果
方法二ToolStripDropDown效果
二 二种方法实现的对比:
方法一 效果类似于QQ,鼠标放在上面时,可以看到显示的效果,但加裁速度有些慢。
方法二的效果类似于MSN,加裁速度比较快,鼠标放在上面时能显示图片的ToolTipText。
三 实现源代码
(1) 方法一。该方法是把图片的位置值存放到DataGridVeiw各个单元格中,在DataGridView的dataGridView1_CellFormatting。这里使用到了e.Value中的Object类型。由于 e.Value为Object类型,所以可以直接显示图片。
{
//如果值不为空
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>
/// <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显示图片
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事件发生太频繁,导致一直在加裁图片。
以下为完整代码:
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();
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>
/// <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>
/// <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;
}
以上是主要代码。RtfRichTextBox 下载