/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
*/
8
using System;
9
using System.Collections.Generic;
10
using System.Text;
11
using System.Drawing;
12
using System.Drawing.Drawing2D;
13
using System.Drawing.Imaging;
14
using System.Xml.Serialization;
15
using System.ComponentModel;
16
17
namespace ZH.FileTranferBox
18

{
19
[Serializable]
20
public class FileObject
21
{
22
字段#region 字段
23
private Rectangle _rectangle;
24
private string toolTip;
25
#endregion
26
27
属性#region 属性
28
29
[Browsable(false)]
30
public Point Location
31
{
32
get
33
{
34
return _rectangle.Location;
35
}
36
37
38
set
39
{
40
_rectangle.Location = value;
41
}
42
}
43
[Browsable(false),XmlIgnore]
44
public Rectangle Rectangle
45
{
46
get
47
{
48
return _rectangle;
49
}
50
set
51
{
52
_rectangle = value;
53
}
54
}
55
[Browsable(false), XmlIgnore]
56
public int Width
57
{
58
get
59
{
60
return _rectangle.Width;
61
}
62
set
63
{
64
_rectangle.Width = value;
65
}
66
}
67
[Browsable(false), XmlIgnore]
68
public int Height
69
{
70
get
71
{
72
return _rectangle.Height;
73
}
74
set
75
{
76
_rectangle.Height = value;
77
}
78
}
79
[Browsable(false), XmlIgnore]
80
public int X
81
{
82
get
83
{
84
return _rectangle.X;
85
}
86
set
87
{
88
_rectangle.X = value;
89
}
90
}
91
[Browsable(false), XmlIgnore]
92
public int Y
93
{
94
get
95
{
96
return _rectangle.Y;
97
}
98
set
99
{
100
_rectangle.Y = value;
101
}
102
}
103
[Browsable(false), XmlIgnore]
104
public int Left
105
{
106
get
107
{
108
return _rectangle.Left;
109
}
110
}
111
[Browsable(false), XmlIgnore]
112
public int Top
113
{
114
get
115
{
116
return _rectangle.Top;
117
}
118
}
119
[Browsable(false), XmlIgnore]
120
public int Right
121
{
122
get
123
{
124
return _rectangle.Right;
125
}
126
}
127
[Browsable(false), XmlIgnore]
128
public int Bottom
129
{
130
get
131
{
132
return _rectangle.Bottom;
133
}
134
}
135
[Browsable(false), XmlIgnore]
136
public Size Size
137
{
138
get
139
{
140
return _rectangle.Size;
141
}
142
set
143
{
144
_rectangle.Size = value;
145
}
146
}
147
#endregion
148
149
构造函数#region 构造函数
150
151
public FileObject()
152
{
153
toolTip = "";
154
_rectangle = new Rectangle(0, 0, 0, 0);
155
}
156
public FileObject(Rectangle rect, string tip)
157
{
158
toolTip = tip;
159
_rectangle = new Rectangle(rect.Location, rect.Size);
160
}
161
162
#endregion
163
}
164
}
165

/**//*2
* 创建者:张华3
* 创建日期:2008/7/84
* 更新日期:2008/7/85
* 描述:为类FileLinkButton、类FileTranferItem和类ProcessBar提供基础功能6
* 联系方式:2141408797
*/8
using System;9
using System.Collections.Generic;10
using System.Text;11
using System.Drawing;12
using System.Drawing.Drawing2D;13
using System.Drawing.Imaging;14
using System.Xml.Serialization;15
using System.ComponentModel;16

17
namespace ZH.FileTranferBox18


{19
[Serializable]20
public class FileObject21

{22

字段#region 字段23
private Rectangle _rectangle;24
private string toolTip;25
#endregion26

27

属性#region 属性28

29
[Browsable(false)]30
public Point Location31

{32
get33

{34
return _rectangle.Location;35
}36

37

38
set39

{40
_rectangle.Location = value;41
}42
}43
[Browsable(false),XmlIgnore]44
public Rectangle Rectangle45

{46
get47

{48
return _rectangle;49
}50
set51

{52
_rectangle = value;53
}54
}55
[Browsable(false), XmlIgnore]56
public int Width57

{58
get59

{60
return _rectangle.Width;61
}62
set63

{64
_rectangle.Width = value;65
}66
}67
[Browsable(false), XmlIgnore]68
public int Height69

{70
get71

{72
return _rectangle.Height;73
}74
set75

{76
_rectangle.Height = value;77
}78
}79
[Browsable(false), XmlIgnore]80
public int X81

{82
get83

{84
return _rectangle.X;85
}86
set87

{88
_rectangle.X = value;89
}90
}91
[Browsable(false), XmlIgnore]92
public int Y93

{94
get95

{96
return _rectangle.Y;97
}98
set99

{100
_rectangle.Y = value;101
}102
}103
[Browsable(false), XmlIgnore]104
public int Left105

{106
get107

{108
return _rectangle.Left;109
}110
}111
[Browsable(false), XmlIgnore]112
public int Top113

{114
get115

{116
return _rectangle.Top;117
}118
}119
[Browsable(false), XmlIgnore]120
public int Right121

{122
get123

{124
return _rectangle.Right;125
}126
}127
[Browsable(false), XmlIgnore]128
public int Bottom129

{130
get131

{132
return _rectangle.Bottom;133
}134
}135
[Browsable(false), XmlIgnore]136
public Size Size137

{138
get139

{140
return _rectangle.Size;141
}142
set143

{144
_rectangle.Size = value;145
}146
}147
#endregion148

149

构造函数#region 构造函数150

151
public FileObject()152

{153
toolTip = "";154
_rectangle = new Rectangle(0, 0, 0, 0);155
}156
public FileObject(Rectangle rect, string tip)157

{158
toolTip = tip;159
_rectangle = new Rectangle(rect.Location, rect.Size);160
}161

162
#endregion163
}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

/**//// <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

当文件项移除时,取消注册函数:
1
public 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
public 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 == false) return;
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(0, 0, 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(0, 0), 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(0, 0), 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(0, 0), 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
}

/**//// <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 == false) return;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(0, 0, 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(0, 0), 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
else38
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(0, 0), 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(0, 0), 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
else83

{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);
基本功能是实现了,但还有很多不足和改进的地方,有好的方法希望能够和我共享。谢谢!
0 评论:
发表评论