RadioButtonList 在 ASP.NET 中是再平常不過的控制項
但在 WinForm 中卻怎樣也找不著
若要在 WinForm 使用一個以上的 RadioButton
最常見的做法就是用一個 GroupBox 或 Panel 把多個 RadioButton 包起來
要取值時再跑迴圈去遍歷
但...若不確定有多少的 RadioButton 時...要怎麼預先拉 RadioButton 的數量?
可否從資料庫撈資料以 DataBind 的方式來產生 RadioButton 的數量
這時又需要撰寫 User Control
做法如下
##CONTINUE##
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Drawing
Imports System.Data
Imports System.Text
Imports System.Windows.Forms
Imports System.Collections
Imports tw.org.mirdc
Partial Public Class RadioButtonList
Inherits UserControl
#Region "Variable"
Private _dataSource As [Object]
Private _mappings As ButtonValueMapping()
Private _internalDataSource As [Object]
Private _displayMember As String
Private _valueMember As String
Private _selectedValue As String
Private _selectedName As String
#End Region
#Region "ctor."
Public Sub New()
InitializeComponent()
End Sub
#End Region
#Region "prop"
Public Property DataSource() As System.Object
Get
Return _dataSource
End Get
Set(ByVal value As System.Object)
_dataSource = value
End Set
End Property
Public Property DisplayMember() As String
Get
Return _displayMember
End Get
Set(ByVal value As String)
_displayMember = value
End Set
End Property
Public Property ValueMember() As String
Get
Return _valueMember
End Get
Set(ByVal value As String)
_valueMember = value
End Set
End Property
Public Property SelectedValue() As String
Get
Return _selectedValue
End Get
Set(ByVal value As String)
If value IsNot Nothing Then
_selectedValue = value
SetValue(value)
End If
End Set
End Property
Public Property SelectedName() As String
Get
Return _selectedName
End Get
Set(ByVal value As String)
If value IsNot Nothing Then
_selectedName = value
SetValue(value)
End If
End Set
End Property
#End Region
#Region "event"
Public Delegate Sub RadioSelectedHandler(ByVal sender As Object, ByVal e As SelectedEventArgs)
Public Event RadioItemSeleted As RadioSelectedHandler
#End Region
#Region "public method"
Public Sub DataBind()
If _dataSource Is Nothing Then
Throw New NullReferenceException("Null reference in Property: DataSource ")
End If
PrepareData()
DrawControl()
End Sub
#End Region
#Region "internal function"
Private Sub DrawControl()
Panel1.Controls.Clear()
Dim count As Integer = _mappings.Length
Dim height As Integer = 0
Dim width As Integer = 0
Dim x_aris As Integer = 0
Dim y_aris As Integer = 0
For i As Integer = 0 To count - 1
Dim radio As New RadioButton()
radio.Name = i.ToString()
radio.Text = _mappings(i).Text
radio.AutoSize = True
Panel1.Controls.Add(radio)
height += radio.Height
radio.Location = New Point(x_aris + width, y_aris)
width += radio.Width
AddHandler radio.Click, New EventHandler(AddressOf radio_Click)
Next
If count > 0 Then
Panel1.Height = DirectCast(Panel1.Controls(_mappings(0).Index.ToString()), RadioButton).Height
Me.Height = Panel1.Height
Me.Panel1.Width = width
Me.Width = width
End If
End Sub
Private Sub PrepareData()
_internalDataSource = Nothing
If TypeOf _dataSource Is DataTable Then
_internalDataSource = DirectCast(_dataSource, DataTable).DefaultView
End If
If TypeOf _dataSource Is DataView Then
_internalDataSource = _dataSource
ElseIf TypeOf _dataSource Is List(Of mirdc.Entity.LookupTable) Then
_internalDataSource = _dataSource
End If
If _internalDataSource Is Nothing Then
Throw New InvalidCastException("The data source is not a desinged type.")
End If
If TypeOf _internalDataSource Is DataView Then
Dim radioCount As Integer = DirectCast(_internalDataSource, DataView).Count
_mappings = New ButtonValueMapping(radioCount - 1) {}
Try
For i As Integer = 0 To radioCount - 1
_mappings(i).Index = i
_mappings(i).Text = DirectCast(_internalDataSource, DataView)(i)(_displayMember).ToString()
If _valueMember Is Nothing OrElse _valueMember = String.Empty Then
_mappings(i).Value = i.ToString()
Else
_mappings(i).Value = DirectCast(_internalDataSource, DataView)(i)(_valueMember).ToString()
End If
Next
Catch e As Exception
Throw e
End Try
End If
End Sub
Private Sub radio_Click(ByVal sender As Object, ByVal e As EventArgs)
_selectedValue = _mappings(Integer.Parse(DirectCast(sender, RadioButton).Name)).Value
Dim se As New SelectedEventArgs()
se.Value = _mappings(Integer.Parse(DirectCast(sender, RadioButton).Name)).Value
RaiseEvent RadioItemSeleted(Me, se)
End Sub
Private Sub SetValue(ByVal value As String)
If _mappings Is Nothing Then
Throw New NullReferenceException("Data has not bound to the control")
End If
For Each map As ButtonValueMapping In _mappings
If map.Value = value Then
DirectCast(Panel1.Controls(map.Index.ToString()), RadioButton).Checked = True
End If
Next
End Sub
#End Region
Friend Structure ButtonValueMapping
Public Index As Integer
Public Value As String
Public Text As String
End Structure
Public Class SelectedEventArgs
Inherits EventArgs
Public Value As String
End Class
End Class
編譯完後就會在工具箱出現了,這時應該知道該怎麼用了吧? 拖拉 & 複製貼上是 programmer 的強項
CheckBoxList亦可仿製

沒有留言:
張貼留言