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