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)实现.

ToolStripLayoutStyle 值:

   1Table

   2 Flow

   3 StackWithOverflow

   4 HorizontalStackWithOverflow 

   5 VerticalStackWithOverflow

如果 LayoutStyle 属性设置为 FlowTable,将不会显示大小调整手柄。

这里设置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(1515);//图片大小
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;

        }

 

 

 

 以上是主要代码。RtfRichTextBox 下载 

 

 

posted @ 2009-12-26 17:14  ☆会飞的鱼☆  阅读(5458)  评论(10编辑  收藏  举报