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亦可仿製
沒有留言:
張貼留言