一个使用用户控件(包括组件)的演示。

1.

Imports System.ComponentModel
Public Class pic
Inherits System.Windows.Forms.UserControl

#Region " Windows 窗体设计器生成的代码 "

'UserControl1 重写 dispose 以清理组件列表。
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub

'Windows 窗体设计器所必需的
Private components As System.ComponentModel.IContainer

'注意:以下过程是 Windows 窗体设计器所必需的
'可以使用 Windows 窗体设计器修改此过程。
'不要使用代码编辑器修改它。

  1<system.diagnostics.debuggerstepthrough()> Private Sub InitializeComponent()   
  2'   
  3'pic   
  4'   
  5Me.Name = "pic"   
  6Me.Size = New System.Drawing.Size(48, 48) 
  7
  8End Sub 
  9
 10#End Region 
 11
 12Public Const m_maxlen As Integer = 48 '固定的宽和高   
 13Public Const m_maxheight As Integer = 48   
 14Public Sub New(ByVal m As image) '主要是用于在piccontrols组件中创建实例时使用   
 15MyBase.New() 
 16
 17'该调用是 Windows 窗体设计器所必需的。   
 18InitializeComponent() 
 19
 20'在 InitializeComponent() 调用之后添加任何初始化   
 21m_image = m   
 22End Sub   
 23Public Sub New()   
 24MyBase.New() 
 25
 26'该调用是 Windows 窗体设计器所必需的。   
 27InitializeComponent() 
 28
 29'在 InitializeComponent() 调用之后添加任何初始化 
 30
 31End Sub 
 32
 33Private m_image As image = image.FromFile("G:\练习\重要的例程\使用问题(在格子中显示图片)\Gounda Takeshi.ico")   
 34<category("grid"), description("设置卡片的图片。")=""> _   
 35Public Property image() As image   
 36Get   
 37Return m_image   
 38End Get   
 39Set(ByVal Value As image)   
 40m_image = Value   
 41Me.Refresh()   
 42End Set   
 43End Property   
 44'绘制边框和图象   
 45Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)   
 46Dim g As Graphics = Me.CreateGraphics   
 47Me.BackColor = Color.White   
 48g.DrawRectangle(System.Drawing.Pens.Black, 0, 0, Me.Width - 1, Me.Height - 1)   
 49Dim ic As Image = CType(m_image, Image)   
 50g.DrawImage(ic, 0, 0)   
 51End Sub   
 52'不允许调整大小   
 53Protected Overrides Sub OnSizeChanged(ByVal e As System.EventArgs)   
 54Me.Size = New Size(m_maxlen, m_maxheight)   
 55End Sub   
 56'匹配否标志   
 57Private m_double As Boolean = False   
 58<category("grid"), description("是否匹配的标志。")=""> _   
 59Public Property doubles() As Boolean   
 60Get   
 61Return m_double   
 62End Get   
 63Set(ByVal Value As Boolean)   
 64m_double = Value   
 65End Set   
 66End Property   
 67Private m_id As Integer   
 68<category("grid"), description("区分是否来自同一图片的标志。")=""> _   
 69Public Property id() As Integer   
 70Get   
 71Return m_id   
 72End Get   
 73Set(ByVal Value As Integer)   
 74m_id = Value   
 75End Set   
 76End Property   
 77  
 78End Class    
 79
 80
 812\. 
 82
 83Imports my_namespace   
 84Imports System.ComponentModel   
 85Public Class piccontrols   
 86Inherits System.ComponentModel.Component 
 87
 88#Region " 组件设计器生成的代码 " 
 89
 90'组件重写 dispose 以清理组件列表。   
 91Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)   
 92If disposing Then   
 93If Not (components Is Nothing) Then   
 94components.Dispose()   
 95End If   
 96End If   
 97MyBase.Dispose(disposing)   
 98End Sub 
 99
100'组件设计器所必需的   
101Private components As System.ComponentModel.IContainer 
102
103'注意:以下过程是组件设计器所必需的   
104'可以使用组件设计器修改此过程。   
105'不要使用代码编辑器修改它。   
106<system.diagnostics.debuggerstepthrough()> Private Sub InitializeComponent()   
107components = New System.ComponentModel.Container()   
108End Sub 
109
110#End Region   
111Public Sub New(ByVal Container As System.ComponentModel.IContainer)   
112MyClass.New() 
113
114'Windows.Forms 类撰写设计器支持所必需的   
115Container.Add(Me) 
116
117changepic() '如果选择的图片发生了变化,那么创建卡片集合也要相应的变化。 
118
119End Sub 
120
121Public Sub New()   
122MyBase.New() 
123
124'该调用是组件设计器所必需的。   
125InitializeComponent() 
126
127'在 InitializeComponent() 调用之后添加任何初始化 
128
129changepic() '如果选择的图片发生了变化,那么创建卡片集合也要相应的变化。 
130
131End Sub   
132'//////////////////////////////////////////////////////////////// 
133
134Dim m_piccontrols As New System.Collections.ArrayList()   
135'总数量   
136<category("grid"), description("集合内卡片的总数。")=""> _   
137Public ReadOnly Property count() As Integer   
138Get   
139Return m_piccontrols.Count   
140End Get   
141End Property   
142'指定位置的卡片(这个对于vb.net是比较特殊的,具有带参数的属性)   
143Default Public ReadOnly Property items(ByVal index As Integer) As pic   
144Get   
145If index &gt;= 0 And index &lt; m_piccontrols.Count Then   
146Return CType(m_piccontrols(index), pic)   
147End If   
148End Get   
149End Property 
150
151Public Sub shuffle() ' 混卡片,也就是生成一组随机的卡片集合。(这里的算法不错!)   
152Dim r As New System.Random()   
153Dim d As New System.Collections.ArrayList()   
154Dim p As pic   
155While (m_piccontrols.Count &gt; 0)   
156Dim removeindex As Integer = r.Next(0, m_piccontrols.Count - 1)   
157p = CType(m_piccontrols(removeindex), my_namespace.pic)   
158m_piccontrols.RemoveAt(removeindex)   
159d.Add(p)   
160End While   
161m_piccontrols = d   
162End Sub 
163
164Private m_image As imagelist   
165<category("grid"), description("选择相应的imagelist控件。")=""> _   
166Public Property imagelist() As imagelist   
167Get   
168Return m_image   
169End Get   
170Set(ByVal Value As imagelist)   
171m_image = Value   
172changepic()   
173End Set   
174End Property   
175'/////////   
176'这个事件比较重要,主要是根据图片的变动来生成不同的卡片集合。   
177Private Sub changepic()   
178If m_image Is Nothing Then Exit Sub   
179Dim i As Integer   
180For i = 0 To m_piccontrols.Count - 1   
181CType(m_piccontrols(i), pic).Dispose() '注意这里。   
182Next   
183m_piccontrols.Clear()   
184Dim j As Integer   
185For i = 0 To m_image.Images.Count - 1   
186For j = 0 To 3   
187Dim p As New pic(m_image.Images(i))   
188p.id = i   
189m_piccontrols.Add(p)   
190Next   
191Next   
192End Sub   
193'由于在排列好后,每个在集合中的卡片的doubles属性都会被设置成true,   
194'所以要在开始一次新的排序时设置所有的卡片该属性为false   
195Public Sub setfalse()   
196Dim i As Integer   
197For i = 0 To m_piccontrols.Count - 1   
198Dim apic As pic = CType(m_piccontrols(i), pic)   
199apic.doubles = False   
200Next   
201End Sub 
202
203End Class    
204
205
2063\. 
207
208Imports System.ComponentModel   
209Public Class picshow   
210Inherits System.Windows.Forms.UserControl 
211
212#Region " Windows 窗体设计器生成的代码 " 
213
214Public Sub New()   
215MyBase.New() 
216
217'该调用是 Windows 窗体设计器所必需的。   
218InitializeComponent() 
219
220'在 InitializeComponent() 调用之后添加任何初始化 
221
222End Sub 
223
224'UserControl 重写 dispose 以清理组件列表。   
225Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)   
226If disposing Then   
227If Not (components Is Nothing) Then   
228components.Dispose()   
229End If   
230End If   
231MyBase.Dispose(disposing)   
232End Sub 
233
234'Windows 窗体设计器所必需的   
235Private components As System.ComponentModel.IContainer 
236
237'注意:以下过程是 Windows 窗体设计器所必需的   
238'可以使用 Windows 窗体设计器修改此过程。   
239'不要使用代码编辑器修改它。   
240<system.diagnostics.debuggerstepthrough()> Private Sub InitializeComponent()   
241components = New System.ComponentModel.Container()   
242End Sub 
243
244#End Region   
245'// 这个程序的原理 //   
246'//先做一个pic控件,可以为其设置相应的图片,不允许改变大小,要重写sizechange,onpait事件 //   
247'//做一个集合组件piccontrols来容纳一定数量的pic卡片,但并不显示它,因为是组件。只是容器 //   
248'//最后做一个picshow控件,用于显示piccontrols.count数量的卡片集合。 //   
249'//比较重要的地方就是如何对卡片进行随机混排(piccontrols的shuffle方法)和picshow控件的 //   
250'//contrains,start方法。尤其注意这里进行排序的方法:是将卡片在集合里就弄混(随机),这样//   
251'//我们取得的每个卡片都是随机的了,然后在picshow控件里根据每个卡片的doubles,id属性来进行 //   
252'//排序,把随机和排序分开了。当然也可以把他们合并写到picshow控件里。不过这里不建议这样。 //   
253'//因为对于piccontrols组件来说,它的集合就是一个随机产生的卡片集合。这样比较好理解。 // 
254
255Private Const m_spacing As Integer = 10 '间隔设置的常量 
256
257Private m_rows As Integer = 2 ' 对于一个阵列来讲,2行应该更有意义。   
258<category("grid"), defaultvalue(2)="" description("矩阵的行。"),=""> _   
259Public Property row() As Integer   
260Get   
261Return m_rows   
262End Get   
263Set(ByVal Value As Integer)   
264If Value &gt; 0 Then   
265m_rows = Value   
266Me.Refresh()   
267End If   
268End Set   
269End Property   
270Private m_columns As Integer = 2   
271<category("grid"), defaultvalue(2)="" description("矩阵的列。"),=""> _   
272Public Property columns() As Integer   
273Get   
274Return m_columns   
275End Get   
276Set(ByVal Value As Integer)   
277If (Value &gt; 0) And (Value Mod 2 = 0) Then   
278m_columns = Value   
279Me.Refresh()   
280Else   
281Throw New Exception("不是有效的列值!请输入2的倍数的列值。")   
282End If   
283End Set   
284End Property   
285Private m_collection As piccontrols   
286<category("grid"), description("指定相应的piccontrols组件。")=""> _   
287Public Property getcontrols() As piccontrols   
288Get   
289Return m_collection   
290End Get   
291Set(ByVal Value As piccontrols)   
292m_collection = Value   
293End Set   
294End Property   
295'绘制边框,由于还没有将卡片加入到me.controls集合,所以只有边框。   
296Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)   
297Dim height As Integer = my_namespace.pic.m_maxheight   
298Dim width As Integer = my_namespace.pic.m_maxlen   
299Me.Width = (width + m_spacing) * m_columns + m_spacing   
300Me.Height = (height + m_spacing) * m_rows + m_spacing   
301Dim g As Graphics = Me.CreateGraphics   
302Dim row, column As Integer   
303For row = 0 To m_rows - 1   
304For column = 0 To m_columns - 1   
305g.DrawRectangle(System.Drawing.Pens.Gray, column * (width + m_spacing) + m_spacing, _   
306row * (height + m_spacing) + m_spacing, width, height)   
307Next   
308Next   
309End Sub 
310
311Private m_double As pic '记录相同的那个卡片 
312
313Private m_last As Integer '记录格子中的最后一个卡片 
314
315'开始排列   
316Public Sub start() 
317
318Me.Controls.Clear() '先清空容器 
319
320If Not IsNothing(m_collection) Then '判断行列之积和卡片数量是否相等   
321If (m_collection.count &lt;&gt; m_rows * m_columns) Then   
322Throw New Exception("卡片数量为:" &amp; CStr(m_collection.count) &amp; "格子数量为:" &amp; CStr(m_rows * m_columns))   
323End If 
324
325'/////////////////////////////////// 
326
327m_last = -2 '初始化,因为从0开始是第一个格子,所以初始值为-2 
328
329m_collection.setfalse() '因为开始一次排序就会把所有的卡片pic的double属性全都设置为true。所以,这里要全都设置回false 
330
331m_collection.shuffle() '将卡片弄混 
332
333Dim cardcount As Integer = 0 '卡片指针   
334Dim row, column As Integer 
335
336For row = 0 To m_rows - 1   
337For column = 0 To m_columns - 1   
338Dim apic As pic = CType(m_collection(cardcount), pic)   
339'加入到me的控件集合   
340Me.Controls.Add(apic)   
341'控件集合中的原有卡片进行遍历,看是否有单个的与新加入的同一个图片的卡片   
342Dim rint As Integer = contrains(apic) 
343
344Select Case rint   
345Case 0 '匹配排列   
346apic.Left = m_double.Left + m_spacing + my_namespace.pic.m_maxlen   
347apic.Top = m_double.Top   
348Case 1 '没有匹配项,间隔排列 
349
350'行,注意一定要使用int进行转化,否则会四舍五入。   
351Dim r As Integer = Int(m_last / (m_rows))   
352'列   
353Dim c As Integer = m_last Mod (m_rows)   
354'取得行列后就可以直接设置位置了。   
355apic.Left = c * (pic.m_maxlen + m_spacing) + m_spacing   
356apic.Top = r * (pic.m_maxheight + m_spacing) + m_spacing 
357
358End Select   
359cardcount += 1 '下一个卡片   
360Next   
361Next   
362MessageBox.Show("排序完成!") 
363
364End If   
365End Sub   
366'排序的函数   
367Public Function contrains(ByVal p As pic) As Integer   
368m_double = Nothing '初始值为空,每次排序前要设置为空。   
369Dim apic As pic   
370Dim i As Integer   
371Dim count As Integer = Me.Controls.Count - 1   
372For i = 0 To count - 1 '从0到末尾-1,把自己排除掉,自己和自己不必要去比较   
373apic = CType(Me.Controls(i), pic)   
374If (apic.id = p.id) And apic.doubles = False Then 'And i &lt;&gt; count   
375apic.doubles = True '匹配   
376p.doubles = True '匹配   
377m_double = apic   
378End If   
379Next   
380'找到匹配的了   
381If Not (m_double Is Nothing) Then   
382Return 0   
383Else   
384m_last += 2 '分隔开一个格子( 这里的格子开始为0,最后为m_collection的count-1)   
385Return 1   
386End If 
387
388End Function   
389End Class</category("grid"),></category("grid"),></category("grid"),></system.diagnostics.debuggerstepthrough()></category("grid"),></category("grid"),></system.diagnostics.debuggerstepthrough()></category("grid"),></category("grid"),></category("grid"),></system.diagnostics.debuggerstepthrough()>
Published At
Categories with Web编程
Tagged with
comments powered by Disqus