/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

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18



19

20

21



22


23

24

25

26

27


28

29

30

31



32

33



34

35

36

37

38

39



40

41

42

43

44

45



46

47



48

49

50

51



52

53

54

55

56

57



58

59



60

61

62

63



64

65

66

67

68

69



70

71



72

73

74

75



76

77

78

79

80

81



82

83



84

85

86

87



88

89

90

91

92

93



94

95



96

97

98

99



100

101

102

103

104

105



106

107



108

109

110

111

112

113



114

115



116

117

118

119

120

121



122

123



124

125

126

127

128

129



130

131



132

133

134

135

136

137



138

139



140

141

142

143



144

145

146

147

148

149


150

151

152



153

154

155

156

157



158

159

160

161

162

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


2

3

4

5



6

7

8

9

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

2



3

4

5

6

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
}


2

3

4

5

6

7



8

9

10

11

12

13

14

15

16

17

18

19

20

21



22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72



73

74

75

76

77

78

79

80

81

82

83



84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

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