一个使用用户控件(包括组件)的演示
发表于:2007-06-30来源:作者:点击数:
标签:
1. Imports System.ComponentModel Public Class pic Inherits System.Windows.Forms.UserControl #Region " Windows 窗体设计器生成的代码 " @#UserControl1 重写 dispose 以清理组件列表。 Protected Overloads Overrides Sub Dispose(ByVal disposing As
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 窗体设计器修改此过程。
@#不要使用代码编辑器修改它。
<System.Diagnostics.De
buggerStepThrough()> Private Sub InitializeComponent()
@#
@#pic
@#
Me.Name = "pic"
Me.Size = New System.Drawing.Size(48, 48)
End Sub
#End Region
Public Const m_maxlen As Integer = 48 @#固定的宽和高
Public Const m_maxheight As Integer = 48
Public Sub New(ByVal m As image) @#主要是用于在pi
clearcase/" target="_blank" >ccontrols组件中创建实例时使用
MyBase.New()
@#该调用是 Windows 窗体设计器所必需的。
InitializeComponent()
@#在 InitializeComponent() 调用之后添加任何初始化
m_image = m
End Sub
Public Sub New()
MyBase.New()
@#该调用是 Windows 窗体设计器所必需的。
InitializeComponent()
@#在 InitializeComponent() 调用之后添加任何初始化
End Sub
Private m_image As image = image.FromFile("G:\练习\重要的例程\使用问题(在格子中显示图片)\Gounda Takeshi.ico")
<Category("grid"), Description("设置卡片的图片。")> _
Public Property image() As image
Get
Return m_image
End Get
Set(ByVal Value As image)
m_image = Value
Me.Refresh()
End Set
End Property
@#绘制边框和图象
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
Dim g As Graphics = Me.CreateGraphics
Me.BackColor = Color.White
g.DrawRectangle(System.Drawing.Pens.Black, 0, 0, Me.Width - 1, Me.Height - 1)
Dim ic As Image = CType(m_image, Image)
g.DrawImage(ic, 0, 0)
End Sub
@#不允许调整大小
Protected Overrides Sub OnSizeChanged(ByVal e As System.EventArgs)
Me.Size = New Size(m_maxlen, m_maxheight)
End Sub
@#匹配否标志
Private m_double As Boolean = False
<Category("grid"), Description("是否匹配的标志。")> _
Public Property doubles() As Boolean
Get
Return m_double
End Get
Set(ByVal Value As Boolean)
m_double = Value
End Set
End Property
Private m_id As Integer
<Category("grid"), Description("区分是否来自同一图片的标志。")> _
Public Property id() As Integer
Get
Return m_id
End Get
Set(ByVal Value As Integer)
m_id = Value
End Set
End Property
End Class
2.
Imports my_namespace
Imports System.ComponentModel
Public Class piccontrols
Inherits System.ComponentModel.Component
#Region " 组件设计器生成的代码 "
@#组件重写 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
@#组件设计器所必需的
Private components As System.ComponentModel.IContainer
@#注意:以下过程是组件设计器所必需的
@#可以使用组件设计器修改此过程。
@#不要使用代码编辑器修改它。
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
components = New System.ComponentModel.Container()
End Sub
#End Region
Public Sub New(ByVal Container As System.ComponentModel.IContainer)
MyClass.New()
@#Windows.Forms 类撰写设计器支持所必需的
Container.Add(Me)
changepic() @#如果选择的图片发生了变化,那么创建卡片集合也要相应的变化。
End Sub
Public Sub New()
MyBase.New()
@#该调用是组件设计器所必需的。
InitializeComponent()
@#在 InitializeComponent() 调用之后添加任何初始化
changepic() @#如果选择的图片发生了变化,那么创建卡片集合也要相应的变化。
End Sub
@#////////////////////////////////////////////////////////////////
Dim m_piccontrols As New System.Collections.ArrayList()
@#总数量
<Category("grid"), Description("集合内卡片的总数。")> _
Public ReadOnly Property count() As Integer
Get
Return m_piccontrols.Count
End Get
End Property
@#指定位置的卡片(这个对于
vb.net是比较特殊的,具有带参数的属性)
Default Public ReadOnly Property items(ByVal index As Integer) As pic
Get
If index >= 0 And index < m_piccontrols.Count Then
Return CType(m_piccontrols(index), pic)
End If
End Get
End Property
Public Sub shuffle() @# 混卡片,也就是生成一组随机的卡片集合。(这里的算法不错!)
Dim r As New System.Random()
Dim d As New System.Collections.ArrayList()
Dim p As pic
While (m_piccontrols.Count > 0)
Dim removeindex As Integer = r.Next(0, m_piccontrols.Count - 1)
p = CType(m_piccontrols(removeindex), my_namespace.pic)
m_piccontrols.RemoveAt(removeindex)
d.Add(p)
End While
m_piccontrols = d
End Sub
Private m_image As imagelist
<Category("grid"), Description("选择相应的imagelist控件。")> _
Public Property imagelist() As imagelist
Get
Return m_image
End Get
Set(ByVal Value As imagelist)
m_image = Value
changepic()
End Set
End Property
@#/////////
@#这个事件比较重要,主要是根据图片的变动来生成不同的卡片集合。
Private Sub changepic()
If m_image Is Nothing Then Exit Sub
Dim i As Integer
For i = 0 To m_piccontrols.Count - 1
CType(m_piccontrols(i), pic).Dispose() @#注意这里。
Next
m_piccontrols.Clear()
Dim j As Integer
For i = 0 To m_image.Images.Count - 1
For j = 0 To 3
Dim p As New pic(m_image.Images(i))
p.id = i
m_piccontrols.Add(p)
Next
Next
End Sub
@#由于在排列好后,每个在集合中的卡片的doubles属性都会被设置成true,
@#所以要在开始一次新的排序时设置所有的卡片该属性为false
Public Sub setfalse()
Dim i As Integer
For i = 0 To m_piccontrols.Count - 1
Dim apic As pic = CType(m_piccontrols(i), pic)
apic.doubles = False
Next
End Sub
End Class
3.
Imports System.ComponentModel
Public Class picshow
Inherits System.Windows.Forms.UserControl
#Region " Windows 窗体设计器生成的代码 "
Public Sub New()
MyBase.New()
@#该调用是 Windows 窗体设计器所必需的。
InitializeComponent()
@#在 InitializeComponent() 调用之后添加任何初始化
End Sub
@#UserControl 重写 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 窗体设计器修改此过程。
@#不要使用代码编辑器修改它。
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
components = New System.ComponentModel.Container()
End Sub
#End Region
@#// 这个程序的原理 //
@#//先做一个pic控件,可以为其设置相应的图片,不允许改变大小,要重写sizechange,onpait事件 //
@#//做一个集合组件piccontrols来容纳一定数量的pic卡片,但并不显示它,因为是组件。只是容器 //
@#//最后做一个picshow控件,用于显示piccontrols.count数量的卡片集合。 //
@#//比较重要的地方就是如何对卡片进行随机混排(piccontrols的shuffle方法)和picshow控件的 //
@#//contrains,start方法。尤其注意这里进行排序的方法:是将卡片在集合里就弄混(随机),这样//
@#//我们取得的每个卡片都是随机的了,然后在picshow控件里根据每个卡片的doubles,id属性来进行 //
@#//排序,把随机和排序分开了。当然也可以把他们合并写到picshow控件里。不过这里不建议这样。 //
@#//因为对于piccontrols组件来说,它的集合就是一个随机产生的卡片集合。这样比较好理解。 //
Private Const m_spacing As Integer = 10 @#间隔设置的常量
Private m_rows As Integer = 2 @# 对于一个阵列来讲,2行应该更有意义。
<Category("grid"), Description("矩阵的行。"), DefaultValue(2)> _
Public Property row() As Integer
Get
Return m_rows
End Get
Set(ByVal Value As Integer)
If Value > 0 Then
m_rows = Value
Me.Refresh()
End If
End Set
End Property
Private m_columns As Integer = 2
<Category("grid"), Description("矩阵的列。"), DefaultValue(2)> _
Public Property columns() As Integer
Get
Return m_columns
End Get
Set(ByVal Value As Integer)
If (Value > 0) And (Value Mod 2 = 0) Then
m_columns = Value
Me.Refresh()
Else
Throw New Exception("不是有效的列值!请输入2的倍数的列值。")
End If
End Set
End Property
Private m_collection As piccontrols
<Category("grid"), Description("指定相应的piccontrols组件。")> _
Public Property getcontrols() As piccontrols
Get
Return m_collection
End Get
Set(ByVal Value As piccontrols)
m_collection = Value
End Set
End Property
@#绘制边框,由于还没有将卡片加入到me.controls集合,所以只有边框。
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
Dim height As Integer = my_namespace.pic.m_maxheight
Dim width As Integer = my_namespace.pic.m_maxlen
Me.Width = (width + m_spacing) * m_columns + m_spacing
Me.Height = (height + m_spacing) * m_rows + m_spacing
Dim g As Graphics = Me.CreateGraphics
Dim row, column As Integer
For row = 0 To m_rows - 1
For column = 0 To m_columns - 1
g.DrawRectangle(System.Drawing.Pens.Gray, column * (width + m_spacing) + m_spacing, _
row * (height + m_spacing) + m_spacing, width, height)
Next
Next
End Sub
Private m_double As pic @#记录相同的那个卡片
Private m_last As Integer @#记录格子中的最后一个卡片
@#开始排列
Public Sub start()
Me.Controls.Clear() @#先清空容器
If Not IsNothing(m_collection) Then @#判断行列之积和卡片数量是否相等
If (m_collection.count <> m_rows * m_columns) Then
Throw New Exception("卡片数量为:" & CStr(m_collection.count) & "格子数量为:" & CStr(m_rows * m_columns))
End If
@#///////////////////////////////////
m_last = -2 @#初始化,因为从0开始是第一个格子,所以初始值为-2
m_collection.setfalse() @#因为开始一次排序就会把所有的卡片pic的double属性全都设置为true。所以,这里要全都设置回false
m_collection.shuffle() @#将卡片弄混
Dim cardcount As Integer = 0 @#卡片指针
Dim row, column As Integer
For row = 0 To m_rows - 1
For column = 0 To m_columns - 1
Dim apic As pic = CType(m_collection(cardcount), pic)
@#加入到me的控件集合
Me.Controls.Add(apic)
@#控件集合中的原有卡片进行遍历,看是否有单个的与新加入的同一个图片的卡片
Dim rint As Integer = contrains(apic)
Select Case rint
Case 0 @#匹配排列
apic.Left = m_double.Left + m_spacing + my_namespace.pic.m_maxlen
apic.Top = m_double.Top
Case 1 @#没有匹配项,间隔排列
@#行,注意一定要使用int进行转化,否则会四舍五入。
Dim r As Integer = Int(m_last / (m_rows))
@#列
Dim c As Integer = m_last Mod (m_rows)
@#取得行列后就可以直接设置位置了。
apic.Left = c * (pic.m_maxlen + m_spacing) + m_spacing
apic.Top = r * (pic.m_maxheight + m_spacing) + m_spacing
End Select
cardcount += 1 @#下一个卡片
Next
Next
MessageBox.Show("排序完成!")
End If
End Sub
@#排序的函数
Public Function contrains(ByVal p As pic) As Integer
m_double = Nothing @#初始值为空,每次排序前要设置为空。
Dim apic As pic
Dim i As Integer
Dim count As Integer = Me.Controls.Count - 1
For i = 0 To count - 1 @#从0到末尾-1,把自己排除掉,自己和自己不必要去比较
apic = CType(Me.Controls(i), pic)
If (apic.id = p.id) And apic.doubles = False Then @#And i <> count
apic.doubles = True @#匹配
p.doubles = True @#匹配
m_double = apic
End If
Next
@#找到匹配的了
If Not (m_double Is Nothing) Then
Return 0
Else
m_last += 2 @#分隔开一个格子( 这里的格子开始为0,最后为m_collection的count-1)
Return 1
End If
End Function
End Class
原文转自:http://www.ltesting.net