I'm a novice in VB.net and trying to create a user control that holds a groupbox containing a variable number of radiobuttons evenly spread. The groupbox and radiobutton are different controls. I managed to get the groupbox with the radiobuttons on a form, but I do not understand why the radiobuttons do not act as a group. (they can all be checked together).

this is what I have so far;

Calling the control and add it to the form

Dim envGrpPanel As MyRadioGroupBox = New MyRadioGroupBox("Environments", arrNames, "")
With envGrpPanel
 .Dock = DockStyle.Fill
End With
tblContainerPanel.Controls.Add(envGrpPanel, 0, 0)

GROUPBOX USERCONTROL

Imports System.Windows.Forms
Imports JIM.MyRadioButton

Public Class MyRadioGroupBox
Inherits UserControl

Public Sub New(ByVal grpBoxName As String, ByVal controlValues As Array, _ 
ByVal construct As Object)

 InitializeComponent()
 Me.GroupBox.Text = grpBoxName

 For i As Integer = 0 To controlValues.Length - 1
  Dim myRdn As MyRadioButton = New MyRadioButton(controlValues.GetValue(i), i)
  myRdn.AutoSize = True
  myRdn.Dock = DockStyle.Fill
  Me.FlowLayoutPanel1.Controls.Add(myRdn)
 End Sub
End Class

ps. When I manually add some buttons to the flowcontrol within the groupbox, it works properly. anyone?

USER CONTROL MyRadioButton

Imports System.Windows.Forms
Imports JIM.MyRadioButton

Public Class MyRadioButton
 Inherits UserControl

 Public Event rbnClick(ByVal sender As MyRadioButton, ByVal radioButtonName As System.EventArgs)

  Public Sub New(ByVal btnText As String, ByVal tabStop As Integer)
  InitializeComponent()

  Me.RadioButton.Text = btnText
  AddHandler Me.RadioButton.CheckedChanged, AddressOf RadioButton_CheckedChanged
 End Sub

  Private Sub RadioButton_CheckedChanged(sender As Object, e As EventArgs) Handles RadioButton.CheckedChanged
        RaiseEvent rdnBtnClicked(sender, e)
  End Sub
End Class

for clearity, a part of the InitializeComponent of the usercontrol GroupBox

'NOTE: The following procedure is required by the Windows Form Designer
'It can be modified using the Windows Form Designer.  
'Do not modify it using the code editor.
<System.Diagnostics.DebuggerStepThrough()> _
Private Sub InitializeComponent()
    Me.GroupBox = New System.Windows.Forms.GroupBox()
    Me.FlowLayoutPanel1 = New System.Windows.Forms.FlowLayoutPanel()
    Me.GroupBox.SuspendLayout()
    Me.SuspendLayout()
    '
    'GroupBox
    '
    Me.GroupBox.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None
    Me.GroupBox.Controls.Add(Me.FlowLayoutPanel1)

Changed Sub looping through custom radiocontrols

Private Sub rdnBtnClicked(ByVal sender As MyRadioButton, ByVal e As System.EventArgs)
        For Each oControl As Object In FlowLayoutPanel1.Controls
            Dim myRdn As MyRadioButton = oControl
            System.Console.WriteLine("MyRdn: " & myRdn.Name & ". Sender.name: " & sender.Name)
            If myRdn.Name <> sender.Name Then
                ' Not the one which has just been set, uncheck it
                myRdn.Checked = False
            End If
        Next

    End Sub
有帮助吗?

解决方案

There is no automatic way in Windows Forms to do what you want, as the logic which makes the radio buttons enclosed in one Panel or GroupBox behave like radio buttons seems to be tied to them being added during design time already.

But you could work around that pretty easily. Set the radio button AutoCheck property to False, so that it does not try to do anything special for you. Then listen for the clicked event in your container class and whenever one of the buttons is clicked, go through them all, checking the one which was clicked, unchecking the rest of them.

It works for me like this -- I even got rid of MyRadioButton for simplicity, as it was not required anymore:

MyRadioGroupBox.vb

Public Class MyRadioGroupBox
    Inherits UserControl

    Public Sub New(ByVal grpBoxName As String, ByVal controlValues As Array, _
    ByVal construct As Object)

        InitializeComponent()
        Me.GroupBox.Text = grpBoxName

        For i As Integer = 0 To controlValues.Length - 1
            ' Create a regular RadioButton
            Dim myRdn As RadioButton = New RadioButton
            myRdn.Text = controlValues.GetValue(i)
            myRdn.AutoSize = True
            ' Disable its AutoCheck functionality
            myRdn.AutoCheck = False
            myRdn.Dock = DockStyle.Fill
            Me.FlowLayoutPanel1.Controls.Add(myRdn)
            ' Register for its Click event
            AddHandler myRdn.Click, AddressOf MyRadioGroupBox_rdnBtnClicked
        Next
    End Sub

    Private Sub MyRadioGroupBox_rdnBtnClicked(sender As Object, e As EventArgs)
        ' For all child controls in the panel...
        For Each oControl As Object In FlowLayoutPanel1.Controls
            ' ...get it as a RadioButton and compare with the event sender,
            ' i.e. the button which has just been clicked.
            Dim myRdn As RadioButton = oControl
            If Object.ReferenceEquals(myRdn, sender) Then
                ' Match - it's the one which has just been clicked, check it
                myRdn.Checked = True
            Else
                ' Does not match - it's some other one, uncheck it
                myRdn.Checked = False
            End If
        Next
    End Sub

End Class
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top