实现类似qq的显示文件传输信息的控件(改进版)

Posted on 2008-07-11 13:26  少林  阅读(3221)  评论(10编辑  收藏

 

    代码:
    /Files/sherlockhua/filetransferbox.rar
    /Files/sherlockhua/TransferBoxEx.rar(改进版)
     实现效果图:
       

       最近在做一个可在局域网中聊天的聊天工具,因为要支持多文件传输功能,所以显示多文件传输状态便成了一个问题。我们都用过qq,当进行多文件传输时,它可以以列表的形式把正在传输的文件信息显示出来。显示的内容有文件图标,文件名,发送或者接受文件,进度条,文件大小还有一些取消,保存之类的按钮。而且当正在传输的文件比较多,客户区显示不了时。就会出现一个滚动条,用来显示所有的发送或接收文件的信息。

好了,大概得轮廓都已经了解了。现在就可以开始着手写控件了。我们知道列表中的每一项都是一个文件信息,我们就可以把每一个文件信息作为一个类,然后在这个类之中绘制各种文件信息。自然而然,我们可以分辨出以下几个类:FileTransferItem类、FileLinkButton类、ProcessBar类。其中FileTransferItem类用来代表一个文件信息项。FileLinkButton提供类似LinkButton类的按钮功能,ProcessBar类提供进度条的功能。然而为了在正确位置进行绘制控件,就必须记下每一对象的位置。因此,我们可以用一个基类FileObject来替提供位置信息,其他的类都继承它。部分代码如下:

  1/*
  2 * 创建者:张华
  3 * 创建日期:2008/7/8
  4 * 更新日期:2008/7/8
  5 * 描述:为类FileLinkButton、类FileTranferItem和类ProcessBar提供基础功能
  6 * 联系方式:214140879
  7 */

  8using System;
  9using System.Collections.Generic;
 10using System.Text;
 11using System.Drawing;
 12using System.Drawing.Drawing2D;
 13using System.Drawing.Imaging;
 14using System.Xml.Serialization;
 15using System.ComponentModel;
 16
 17namespace ZH.FileTranferBox
 18{
 19    [Serializable]
 20    public class FileObject
 21    {
 22        字段
 26
 27        属性
148
149        构造函数
163    }

164}

165

为了更好的实现封装性和隐蔽性。在类FileTransferItem增加注册事件的函数。

 1/// <summary>
 2        /// 注册事件
 3        /// </summary>

 4        public void RegisterEvent()
 5        {
 6            _parent.MouseClick += (MouseEventHandler)_delegates[0];
 7            _parent.MouseDown += (MouseEventHandler)_delegates[1];
 8            _parent.MouseMove += (MouseEventHandler)_delegates[2];
 9            _parent.Paint += (PaintEventHandler)_delegates[3];
10     }

11

当文件项移除时,取消注册函数:

1public void UnRegisterEvent()
2        {
3            _parent.MouseClick -= (MouseEventHandler)_delegates[0];
4            _parent.MouseDown -= (MouseEventHandler)_delegates[1];
5            _parent.MouseMove -= (MouseEventHandler)_delegates[2];
6            _parent.Paint -= (PaintEventHandler)_delegates[3];
7     }

8

文件信息项绘制函数:

  1  /// <summary>
  2        /// 控件绘制函数
  3        /// </summary>
  4        /// <param name="sender"></param>
  5        /// <param name="e"></param>

  6        private void OnPaint(object sender, PaintEventArgs e)
  7        {
  8            if (visible == falsereturn;
  9            Graphics g = e.Graphics;
 10          
 11            Brush txtBrush = null;
 12            StringFormat format = new StringFormat();
 13            format.Alignment = StringAlignment.Near;
 14            format.Trimming = StringTrimming.EllipsisWord;
 15            format.FormatFlags = StringFormatFlags.NoWrap;
 16
 17            rectImage.X =Rectangle.X + LEFTSPACE;
 18            rectImage.Y =Rectangle.Y+ TOPSPACE;
 19
 20            if (extImage == null)
 21            {
 22                System.Diagnostics.Debug.WriteLine("文件图像为空");
 23                return;
 24            }

 25            //绘制左边的文件图像
 26            g.DrawImage(extImage, rectImage, new Rectangle(00, extImage.Width, extImage.Height), GraphicsUnit.Pixel);
 27            
 28            //绘制标题(“发送文件”或“接受文件”)
 29            int fontWidth = _parent.ClientRectangle.Width - rectImage.Width - LEFTSPACE - RIGHTSPACE - LEFTSPACE;
 30            SizeF sizeF = g.MeasureString(caption, _parent.Font);
 31            sizeF.Width = Math.Min(fontWidth, sizeF.Width);
 32            RectangleF rectF = new RectangleF(new PointF(00), sizeF);
 33            rectF.X = Rectangle.X + LEFTSPACE + rectImage.Width + LEFTSPACE;
 34            rectF.Y = Rectangle.Y + TOPSPACE;
 35            if (mouseHover)
 36                txtBrush = new SolidBrush(hoverFontColor.IsEmpty?_parent.HoverFontColor:hoverFontColor);
 37            else
 38                txtBrush = new SolidBrush(normalFontColor.IsEmpty?_parent.NormalFontColor:normalFontColor);
 39            g.DrawString(caption, _parent.Font, txtBrush, rectF, format);
 40
 41            //绘制文件名
 42            sizeF = g.MeasureString(fileName, _parent.Font);
 43            sizeF.Width = Math.Min(fontWidth, sizeF.Width);
 44            RectangleF rectF2 = new RectangleF(new PointF(00), sizeF);
 45            rectF2.X = Rectangle.X + LEFTSPACE + rectImage.Width + LEFTSPACE;
 46            rectF2.Y = rectF.Y + rectF.Height + LEFTSPACE;
 47
 48            g.DrawString(fileName, _parent.Font, txtBrush, rectF2, format);
 49
 50            //绘制进度条
 51            Rectangle rectProcess = Rectangle.Empty;
 52            rectProcess.X = Rectangle.X + LEFTSPACE;
 53            rectProcess.Y = Rectangle.Y + rectImage.Height + BOTTOMSPACE*2;
 54            rectProcess.Width = Rectangle.Width - LEFTSPACE * 2;
 55            rectProcess.Height = LEFTSPACE * 4;
 56
 57            processBar.Rectangle = rectProcess;
 58            processBar.Paint(g);
 59
 60            //绘制文件大小
 61            string fileSizeDisplay = Format.ToString(transferSize) + "/" + fileSize;
 62            sizeF = g.MeasureString(fileSizeDisplay,_parent.Font);
 63            RectangleF fileSizeRectF = new RectangleF(new Point(00), sizeF);
 64            fileSizeRectF.X = processBar.Right - sizeF.Width - LEFTSPACE;
 65            fileSizeRectF.Y = processBar.Y + processBar.Height + LEFTSPACE;
 66            g.DrawString(fileSizeDisplay, _parent.Font, txtBrush, fileSizeRectF, format);
 67            
 68
 69            //绘制按钮
 70            Rectangle rectButton = Rectangle.Empty;
 71            if (transferType == TransferType.SendFile)
 72            {
 73                rectButton.X = rectProcess.Right - 50 - RIGHTSPACE;
 74                rectButton.Y = (int)fileSizeRectF.Y + (int)fileSizeRectF.Height + RIGHTSPACE;
 75                rectButton.Width = 50;
 76                rectButton.Height = 20;
 77
 78                lbCancel.Rectangle = rectButton;
 79                lbCancel.Visible = true;
 80                lbCancel.Paint(g);
 81            }

 82            else
 83            {
 84                int width = (Rectangle.Width-LEFTSPACE*4/ 3;
 85                rectButton.X = rectProcess.Right - width - RIGHTSPACE;
 86                rectButton.Y = (int)fileSizeRectF.Height + RIGHTSPACE + (int)fileSizeRectF.Y;
 87                rectButton.Width = 50;
 88                rectButton.Height = 20;
 89
 90                lbReject.Rectangle = rectButton;
 91                lbReject.Visible = true;
 92                lbReject.Paint(g);
 93
 94                rectButton.X = rectProcess.Right - width * 2 - RIGHTSPACE * 2;
 95                rectButton.Y = (int)fileSizeRectF.Height + RIGHTSPACE + (int)fileSizeRectF.Y;
 96                rectButton.Width = 50;
 97                rectButton.Height = 20;
 98
 99                lbSave.Rectangle = rectButton;
100                lbSave.Visible = true;
101                lbSave.Paint(g);
102
103                rectButton.X = rectProcess.Right - width * 3 - RIGHTSPACE * 3;
104                rectButton.Y = (int)fileSizeRectF.Height + RIGHTSPACE + (int)fileSizeRectF.Y;
105                rectButton.Width = 50;
106                rectButton.Height = 20;
107
108                lbSaveAs.Rectangle = rectButton;
109                lbSaveAs.Visible = true;
110                lbSaveAs.Paint(g);
111            }

112        }

    这里只是列出关键代码,具体代码参考源代码。
    如何使用:
        this.fileTranferBox1.AddItem(fileName, info.Length, ZH.FileTranferBox.TransferType.SendFile);
    基本功能是实现了,但还有很多不足和改进的地方,有好的方法希望能够和我共享。谢谢!

随笔 - 70, 文章 - 4, 评论 - 307

Copyright © 2020 少林
Powered by .NET 5.0.0 on Kubernetes