会飞的鱼前段时间写了篇文章,介绍如何实现类似QQ表情对话框的功能,具体描述见文章《c# 类似于QQ表情弹出框功能的二种实现方法》。刚好最近我也有类似的需求,我刚开始的想法是在Panel中动态创建PictureBox来加载QQ表情,如:

      private void InitImageControl(int colCount, int rowCount)
        {
            for (int i = 0; i < rowCount; i++)
            {
                for (int j = 0; j < colCount; j++)
                {
                    PictureBox picBox = new PictureBox();
                    picBox.SizeMode = PictureBoxSizeMode.CenterImage;
                    picBox.Image = @"d:\qqface\1.gif"; //从文件中加载图片
                       Size controlSize = new Size(imgWidth, imgHeight);
                    picBox.Size = controlSize;
                    int controlLoctionX = controlSize.Width * j;
                    int controlLoctionY = controlSize.Height * i;
                    picBox.Location = new Point(controlLoctionX, controlLoctionY);
                    picBox.MouseHover += new EventHandler(picBox_MouseHover);
                    panel1.Controls.Add(picBox);
                }
            }
        }
这样实现的方式比较简单,但是速度却非常慢,于是就放弃了这个想法。
突然想到,利用网页来加载图片,效率可能会高很多的(事实证明也是如此),于是考虑在Panel中加载个WebBrowser,然后动态的加载网页来实现。
首先制作了类似QQ表情对话框展示效果的网页(代码下载),截图如下:
image 
由于代码比较简单,就直接贴代码了:
加载QQ表情
        private int currentPageIndex = 1;//当前页代码
        private int pageSize = 0;//总共页数

        ///<summary>
        /// 加载QQ表情
         /// </summary>
        /// <param name="currentPage">当前页</param>
        /// <param name="rowCount">每页显示表情的行数</param>
        /// <param name="colCount">每页显示表情的列数</param>
        private void LoadQQFace(int currentPage,int rowCount,int colCount)
        {
            currentPageIndex = currentPage;
            string _template = string.Empty;
            string templateFile = Application.StartupPath + @"\template.html";//网页模版
            _template = File.ReadAllText(templateFile);
            //图像的配置文件
             string _configInfo = string.Empty;
            string configFile = Application.StartupPath + @"\face.xml";
            DataSet ds = new DataSet();
            ds.ReadXml(configFile);
            DataTable dtFaces = ds.Tables[0];
            int totalCount =dtFaces.Rows.Count;
            pageSize = totalCount % (rowCount * colCount) == 0 ? totalCount / (rowCount * colCount) : totalCount / (rowCount * colCount)+1;
            //加载表格
            string tableRowContent=string.Empty;
            for (int i = 1; i <=rowCount; i++)
            {
                string tableRow = "<tr>";
                for (int j= 1; j <=colCount; j++)
                {
                    int faceRowIndex=(i-1)*colCount+(currentPageIndex-1)*rowCount*colCount+j;
                    if (faceRowIndex <totalCount)
                    {
                        string imgPath = dtFaces.Rows[faceRowIndex][0].ToString();
                        imgPath = Application.StartupPath + @"\faces\" + imgPath;
                        tableRow += "<td><p><a href=\'#\' onmouseover=\'showBig(this)\'><img src=\'" + imgPath + "\'/></a></td>";
                    }
                    else
                    {
                        tableRow += "<td></td>";
                    }
                }
                tableRow += "</tr>";
                tableRowContent += tableRow;
            }
            int LeftLimt = 29 * (colCount / 2);
            int RightLimt = (colCount - 3) * 29;
            _template = _template.Replace("$TableRow$", tableRowContent).Replace("$LeftLimt$",LeftLimt.ToString()).Replace("$RightLimt$",RightLimt.ToString());
            //设置网页的背景色和窗体的一致
            Color bgColor = this.BackColor;
            string webBgColor = ColorTranslator.ToHtml(bgColor);
            _template = _template.Replace("$BgColor$", webBgColor);
            //设置导航
             string pageStr = currentPage + "/" + pageSize;
            string navigation = "<div id=\'navigation\'>"+pageStr+"&nbsp;&nbsp;<a href=\'#\' id=\'linkPrev\'>上一页</a>&nbsp;&nbsp;&nbsp;<a href=\'#\' id=\'linkNext\'>下一页</a></div>";
            _template = _template.Replace("$Navigation$", navigation);
            //存到临时文件
            string tempHtmlFile = Path.GetTempPath() + "tempHtmlFile.html";
            File.WriteAllText(tempHtmlFile, _template);
            webBrowser1.Navigate(tempHtmlFile);
            webBrowser1.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(webBrowser1_DocumentCompleted);
            this.Width =29*colCount+21;
            this.Height = 29 * rowCount+80;
          }     
当网页加载完毕后,给分页链接注册事件        
        /// <summary>
        /// 当网页加载完毕后,给分页链接注册事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            //注册翻页事件
            HtmlDocument htmlDoc = webBrowser1.Document;
            HtmlElement linkPrev = htmlDoc.GetElementById("linkPrev");
            if (linkPrev != null)
            {
                linkPrev.Click -= new HtmlElementEventHandler(linkPrev_Click);
                if (currentPageIndex>1)
                   linkPrev.Click+=new HtmlElementEventHandler(linkPrev_Click);
            }
            HtmlElement linkNext = htmlDoc.GetElementById("linkNext");
            if (linkNext != null)
            {
                linkNext.Click -= new HtmlElementEventHandler(linkNext_Click);
                if(currentPageIndex<pageSize)
                linkNext.Click += new HtmlElementEventHandler(linkNext_Click);
            } 
        }

 
分页事件      
        void linkPrev_Click(object sender, HtmlElementEventArgs e)
        {
            LoadQQFace(currentPageIndex -1 , 8, 9);
        }
        void linkNext_Click(object sender, HtmlElementEventArgs e)
        {
            LoadQQFace(currentPageIndex+1, 8, 9);
        }

 

这样就基本实现了QQ表情弹出框的需求了,最终截图如下:
image image
 
留下的问题:
 
如何通过点击QQ表情向聊天对话框发送表情了?如果有人感兴趣,可以和我交流。源码下载

 PS:其实如果不用网页加载,直接把图像画在Panel上,也是可以行,效率也是很快,并且控制起来非常方便,过几天我也贴个代码。

 

版权声明:本文为coding1016原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/coding1016/archive/2010/01/07/1640874.html