• 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 下载 

    作者:chhuic

    出处:http://chhuic.cnblogs.com
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

  • 相关阅读:
    Git 分支开发规范
    小程序技术调研
    弹性布局
    vue 自定义指令的魅力
    记一次基于 mpvue 的小程序开发及上线实战
    mpvue学习笔记-之微信小程序数据请求封装
    微信小程序开发框架 Wepy 的使用
    Hbuilder 开发微信小程序的代码高亮
    luogu3807 【模板】 卢卡斯定理
    luogu1955 [NOI2015] 程序自动分析
  • 原文地址:https://www.cnblogs.com/chhuic/p/1632889.html
Copyright © 2020-2023  润新知