none
How to force selection of a radio botton before form is allowed to close RRS feed

  • Question

  • I am working on a Simple Form to send text to a file that is then read and used by a third party software. I am very new at this and not at all familiar with the Visual Studio Syntax.

    The Code for the form is shown below

    PublicClassForm_Select_Machine

     

    PrivateSubForm_Select_Machine_Load() HandlesMyBase.Load

    EndSub

    PrivateSubRadioButtonNC73_CheckedChanged(sender AsObject, e AsEventArgs) HandlesRadioButtonNC73.CheckedChanged

    'Writes NC73 to NC.txt file

    My.Computer.FileSystem.WriteAllBytes("C:\GEOMeasure\Traceability\NC.txt", System.Text.ASCIIEncoding.ASCII.GetBytes("NC73"), False)

    'MessageBox.Show(b.Length.ToString)

    EndSub

    PrivateSubRadioButtonnc74_CheckedChanged(sender AsObject, e AsEventArgs) HandlesRadioButtonnc74.CheckedChanged

    'Writes NC74 to NC.txt file

    My.Computer.FileSystem.WriteAllBytes("C:\GEOMeasure\Traceability\NC.txt", System.Text.ASCIIEncoding.ASCII.GetBytes("NC74"), False)

    EndSub

     

    PrivateSubRadioButton81_CheckedChanged(sender AsObject, e AsEventArgs) HandlesRadioButton81.CheckedChanged

    'Writes NC81 to NC.txt file

    My.Computer.FileSystem.WriteAllBytes("C:\GEOMeasure\Traceability\NC.txt", System.Text.ASCIIEncoding.ASCII.GetBytes("NC81"), False)

    EndSub

    PrivateSubRadioButton90_CheckedChanged(sender AsObject, e AsEventArgs) HandlesRadioButton90.CheckedChanged

    'Writes NC90 to NC.txt file

    My.Computer.FileSystem.WriteAllBytes("C:\GEOMeasure\Traceability\NC.txt", System.Text.ASCIIEncoding.ASCII.GetBytes("NC90"), False)

    EndSub

    PrivateSubRadioButton117_CheckedChanged(sender AsObject, e AsEventArgs) HandlesRadioButton117.CheckedChanged

    'Writes NC117 to NC.txt file

    My.Computer.FileSystem.WriteAllBytes("C:\GEOMeasure\Traceability\NC.txt", System.Text.ASCIIEncoding.ASCII.GetBytes("NC117"), False)

    EndSub

    PrivateSubRadioButton118_CheckedChanged(sender AsObject, e AsEventArgs) HandlesRadioButton118.CheckedChanged

    'Writes NC118 to NC.txt filesender As Object, e As EventArgs

    My.Computer.FileSystem.WriteAllBytes("C:\GEOMeasure\Traceability\NC.txt", System.Text.ASCIIEncoding.ASCII.GetBytes("NC118"), False)

    EndSub

    PrivateSubButtonOK_Click() HandlesButtonOK.Click

    ' Close the form

    Close()

    EndSub

    EndClass

    Current the Form works and the third party software uses the generated text file as intended. However if Someone simply clicks the OK button without selecting a button on the form then the text from the last button selected remains in the text file. If a button is not selected when the OK button is clicked I would like the text "unaddressed" to be sent to the text file. How do I do this? Can I keep the window from closing until a radio button is selected.

    I tried to Insert an image of the form but the page will not let me . Something about verifying my account.


    Wednesday, August 2, 2017 1:19 PM

Answers

  • Try this:

    Private Sub ButtonOK_Click(sender As Object, e As EventArgs) Handles ButtonOK.Click
       If Not RadioButtonNC73.Checked AndAlso Not RadioButtonnc74.Checked AndAlso Not ...... Then
          My.Computer.FileSystem.WriteAllText("C:\...NC.txt", "unaddressed", False, Encoding.ASCII)
       End If
       Close()
    End Sub

    But if you do not want to close the form, then try this:

    Private Sub ButtonOK_Click(sender As Object, e As EventArgs) Handles ButtonOK.Click
       If Not RadioButtonNC73.Checked AndAlso Not RadioButtonnc74.Checked AndAlso Not ...... Then
          MsgBox("Please select an option")
          Return
       End If
       Close()
    End Sub


    Wednesday, August 2, 2017 6:03 PM
  • Viorel

    I like either option you suggest. However when I try to utilize the code and build it  I get Code BC30451 Errors stating RadioButtonNCXX is not declared. It may be inaccessible due to its protection level.

    Here's  the code with your suggestions below.


    Public Class Form_Select_Machine


        Private Sub Form_Select_Machine_Load() Handles MyBase.Load

        End Sub

        Private Sub RadioButtonNC73_CheckedChanged(sender As Object, e As EventArgs) Handles RadioButton1.CheckedChanged
            'Writes NC73 to NC.txt file
            My.Computer.FileSystem.WriteAllBytes("C:\GEOMeasure\Traceability\NC.txt", System.Text.ASCIIEncoding.ASCII.GetBytes("NC73"), False)
            'MessageBox.Show(b.Length.ToString)
        End Sub

        Private Sub RadioButtonNC74_CheckedChanged(sender As Object, e As EventArgs) Handles RadioButton2.CheckedChanged
            'Writes NC74 to NC.txt file
            My.Computer.FileSystem.WriteAllBytes("C:\GEOMeasure\Traceability\NC.txt", System.Text.ASCIIEncoding.ASCII.GetBytes("NC74"), False)
        End Sub


        Private Sub RadioButtonNC81_CheckedChanged(sender As Object, e As EventArgs) Handles RadioButton3.CheckedChanged
            'Writes NC81 to NC.txt file
            My.Computer.FileSystem.WriteAllBytes("C:\GEOMeasure\Traceability\NC.txt", System.Text.ASCIIEncoding.ASCII.GetBytes("NC81"), False)
        End Sub


        Private Sub ButtonOK_Click(sender As Object, e As EventArgs) Handles ButtonOK.Click
            ' Close the form
            If Not RadioButtonNC73.Checked AndAlso Not RadioButtonNC74.Checked AndAlso Not RadioButtonNC81.Checked Then
                MsgBox("Please select an option")
                Return
            End If
            Close()
        End Sub

    End Class

    How do I declare a RadioButton to make this work?

    Saturday, August 5, 2017 5:05 PM
  • In this case, use the new names of checkboxes: RadioButton1, RadioButton2 and RadioButton3 instead of RadioButtonNCxx inside ButtonOK_Click.
    Saturday, August 5, 2017 5:13 PM
  • Thanks Viorel

    I had added a 4th RadioButton for Unaddressed with a default to be checked and hid the button and this worked as well.

    I prefer your method. This is used to tag dimensional data from 3 different Numerical Controlled (NC) machining centers. If the data is  unaddressed I have no idea of which machine the data belongs to. This makes sure the operator has to read and select a machine each time instead of just clicking "OK" and going on.

    Thanks Again.

    Saturday, August 5, 2017 8:03 PM

All replies

  • Old Dog,

    First of all try to use the code button in the code (that is the button with the <>  when you edit) to past in code. 

    I tried to repair it and succeeded, but your code is rare. First of all every time a radiobutton is clicked it changes. Even when you start the program the first button is changed. Beside that if it changes it fires twice, one time when it is unselect and one time as it is select.

    Therefore tell us what you want to do and also past in again your code. 



    Success
    Cor

    Wednesday, August 2, 2017 2:23 PM
  • Try this:

    Private Sub ButtonOK_Click(sender As Object, e As EventArgs) Handles ButtonOK.Click
       If Not RadioButtonNC73.Checked AndAlso Not RadioButtonnc74.Checked AndAlso Not ...... Then
          My.Computer.FileSystem.WriteAllText("C:\...NC.txt", "unaddressed", False, Encoding.ASCII)
       End If
       Close()
    End Sub

    But if you do not want to close the form, then try this:

    Private Sub ButtonOK_Click(sender As Object, e As EventArgs) Handles ButtonOK.Click
       If Not RadioButtonNC73.Checked AndAlso Not RadioButtonnc74.Checked AndAlso Not ...... Then
          MsgBox("Please select an option")
          Return
       End If
       Close()
    End Sub


    Wednesday, August 2, 2017 6:03 PM
  • Viorel,

    The OrElse goes better here, but how do you always know what the OP wants while his code is so much different from what you show?


    Success
    Cor

    Wednesday, August 2, 2017 6:08 PM
  • If a button is not selected when the OK button is clicked I would like the text "unaddressed" to be sent to the text file. How do I do this? Can I keep the window from closing until a radio button is selected.

    That should never be necessary. 

    You need to rearrange that logic so that the file writing code is in the OK button event handler.  Then, ensure one radio button is checked in the designer.   If one button is checked when the form loads then the user can either accept that default or change it, but you will always have one button checked. The code in the OK button handler then detects which radio button was checked, and selects the file to write.

    If you don't want to provide the user with a default, or if you want to allow the user to select a series of files to be written, then don't use radio buttons.

    For account verification see here:
    https://social.msdn.microsoft.com/Forums/en-US/0e3b9d3f-f30b-4bf3-9c6c-b4b4ab11b43e/verify-account-40?forum=reportabug

    Wednesday, August 2, 2017 11:25 PM
  • Here is an option (comments are within the code). I use a Dictionary to get reports from.

    ''' <summary>
    ''' Form has three radio buttons to select from.
    ''' There is a fourth use to ensure no radio buttons
    ''' are selected by checked the fourth and hiding it
    ''' along with not including it in the Dictionary
    ''' where the Dictionay is use to figure out which
    ''' report to save to disk. Yep I made up my own numbers
    ''' for the reports.
    ''' 
    ''' Add as many RadioButtons to the Dictionary as needed.
    ''' </summary>
    Public Class Form1
        Private dict As New Dictionary(Of RadioButton, String)
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            ' possible selections
            dict.Add(RadioButton1, "NC90")
            dict.Add(RadioButton2, "NC91")
            dict.Add(RadioButton3, "NC92")
    
            ' hide selected so the user now must select
            ' from one of the three.
            RadioButton4.Checked = True
            RadioButton4.Visible = False
        End Sub
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            ' Is there a radio button selected ?
    
            ' if not then tell the user to select one
            If Not dict.Any(Function(item) item.Key.Checked) Then
                MessageBox.Show("Please select an option")
            Else
                ' we have a checked radio button so get the item from the
                ' Dictionary and use it to write to disk.
                Dim report As String = dict _
                    .Where(Function(item) item.Key.Checked) _
                    .Select(Function(item) item.Value) _
                    .First
    
                ' do what we came for
                My.Computer.FileSystem.WriteAllBytes("C:\GEOMeasure\Traceability\NC.txt",
                    System.Text.Encoding.ASCII.GetBytes($"{report}"), False)
    
                Close()
    
            End If
        End Sub
        Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
            ' prevent form from closing. You might also care to use a MessageBox and
            ' tell them the reason the form can't be closed :-)
            e.Cancel = Not dict.Any(Function(item) item.Key.Checked)
        End Sub
    End Class


    Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.
    VB Forums - moderator
    profile for Karen Payne on Stack Exchange, a network of free, community-driven Q&A sites


    Wednesday, August 2, 2017 11:37 PM
    Moderator
  • However if Someone simply clicks the OK button without selecting a button on the form then the text from the last button selected remains in the text file.

    That sounds like you're showing this form modally but using the default instance.

    If I'm right, don't do that - it'll create problems down the road. Instead, create a new instance and I'd suggest putting it in a Using block:

    Using f2 As New Form2
        f2.ShowDialog()
    End Using

    Something like that. If you need to pass information into that new instance, that can be done and obviously here you need to pass information back out so that when it returns to the calling form you can then act on it.

    You can set up a Public Read-Only Property that the code in the other form sets. When you're back in the calling form, you can then act on it.

    If you want to make sure that the user has proactively set a radio button, disable the "OK" button until one is selected. To do that, either in the designer or in code, set the .Checked property to false for all of them.

    Don't put that "write to a file" code in that second form at all; the second form is just to be used to allow your user to select the options.

    I might be totally off-base about there being a second form shown modally and if so then ignore what I said here, but your description makes it seem to be the case.

    If I'm right and you need some help with it then message back here Thursday and I'll help you get it all set up.


    "A problem well stated is a problem half solved.” - Charles F. Kettering

    Thursday, August 3, 2017 1:03 AM
  • Old Dog,

    I'll continue my guessing here with an example. I've set up a new form that I've named "UserOptions" as shown below:

    On Form1 (the calling form) I have just one button which, when clicked, will create a new instance of UserOptions and then display it modally:

    Notice above that all radiobuttons are unchecked and the "OK" button is disabled. Once the user selects one of the radiobuttons, one of them will always be checked so we don't need to look to see that nothing is checked, only which one *is* checked. That will make sense when I show the code in a bit.

    Continuing, I'll first test the "Cancel" option. Whether or not they've selected an option, clicking the "Cancel" button or the "X" to close the form dismisses it and returns code execution back to its called (Form1):

    I have "Stop" in various places which works similar to a breakpoint. I often use that to test the logic. I'll run again and this time I'll check one of the options to test it for that:

    Once any of the radiobuttons is checked, the "OK" button is then enabled as shown above. Continuing...

    Now you know the user has chosen "NC81" (whatever in the world that is). The code follows:

    Form1.vb

    Option Strict On
    Option Explicit On
    Option Infer Off
    
    Public Class Form1
        Private Sub Form1_Load(sender As System.Object, _
                               e As System.EventArgs) _
                               Handles MyBase.Load
    
            ' Initialization here (if applicable)...
    
        End Sub
    
        Private Sub _
            Button1_Click(sender As System.Object, _
                          e As System.EventArgs) _
                          Handles Button1.Click
    
            Using uo As New UserOptions
                ' Because I'll use "ShowDialog", the other form
                ' ("UserOptions") will be displayed modally; that
                ' is, it has to be dismissed before execution of
                ' any subsequent code here will take place.
    
                uo.ShowDialog()
    
               ' At this point, the other form ("UserOptions")
                ' has been dismissed. Let's see what they
                ' selected, or if they cancelled it.
    
                If Not uo.UserCancel Then
                    Select Case uo.OptionSelected
                        Case UserOptions.OptionType.NC117
                            Stop
                        Case UserOptions.OptionType.NC118
                            Stop
                        Case UserOptions.OptionType.NC73
                            Stop
                        Case UserOptions.OptionType.NC74
                            Stop
                        Case UserOptions.OptionType.NC81
                            Stop
                        Case UserOptions.OptionType.NC90
                            Stop
                    End Select
                Else
                    ' I don't know what you want to do if the user
                    ' cancels the form so let me know and I'll modify
                    ' this.
    
                    Stop
                End If
            End Using
    
        End Sub
    End Class

    UserOptions.vb

    Option Strict On
    Option Explicit On
    Option Infer Off
    
    Public Class UserOptions
        Public Enum OptionType
            NA
            NC73
            NC74
            NC81
            NC90
            NC117
            NC118
        End Enum
    
        Private _userCancel As Boolean = True
        Private _optionSelected As OptionType
    
        Public Sub New(Optional ByVal previouslySelected As OptionType = OptionType.NA)
            InitializeComponent()
    
            If Not previouslySelected = OptionType.NA Then
                _optionSelected = previouslySelected
            End If
    
            ' By setting an optional parameter (which is a way
            ' that you can allow the user to go back and edit
            ' their selection) I've also disallowed the use of
            ' a default instance; there's no choice now but to
            ' use the "New" keyword when you want to show this
            ' form.
    
        End Sub
    
        Private Sub _
            UserOptions_Load(sender As System.Object, _
                             e As System.EventArgs) _
                             Handles MyBase.Load
    
            With Me
                .AcceptButton = btn_OK
                .CancelButton = btn_Cancel
            End With
    
            btn_OK.Enabled = False
    
            Select Case _optionSelected
                Case OptionType.NC117
                    rb117.Checked = True
    
                Case OptionType.NC118
                    rb118.Checked = True
    
                Case OptionType.NC73
                    rb73.Checked = True
    
                Case OptionType.NC74
                    rb74.Checked = True
    
                Case OptionType.NC81
                    rb81.Checked = True
    
                Case OptionType.NC90
                    rb90.Checked = True
            End Select
    
        End Sub
    
        Private Sub _
            RadioButtonCheckedChanged(sender As System.Object, _
                                      e As System.EventArgs) _
                                      Handles rb117.CheckedChanged, _
                                              rb118.CheckedChanged, _
                                              rb73.CheckedChanged, _
                                              rb74.CheckedChanged, _
                                              rb81.CheckedChanged, _
                                              rb90.CheckedChanged
    
            For Each rb As RadioButton In Me.Controls.OfType(Of RadioButton)()
                If rb.Checked Then
                    Select Case rb.Name
                        Case "rb117"
                            _optionSelected = OptionType.NC117
    
                        Case "rb118"
                            _optionSelected = OptionType.NC118
    
                        Case "rb73"
                            _optionSelected = OptionType.NC73
    
                        Case "rb74"
                            _optionSelected = OptionType.NC74
    
                        Case "rb81"
                            _optionSelected = OptionType.NC81
    
                        Case "rb90"
                            _optionSelected = OptionType.NC90
                    End Select
                End If
            Next
    
            btn_OK.Enabled = True
    
        End Sub
    
        Private Sub _
            btn_OK_Click(sender As System.Object, _
                         e As System.EventArgs) _
                         Handles btn_OK.Click
    
            ' Because the "OK" button is only enabled if one
            ' of the radio buttons is checked (and the
            ' variable "_optionSelected" now knows which
            ' option they chose), I'll set "_userCancel" to
            ' false and close this form.
    
            _userCancel = False
            Close()
    
        End Sub
    
        Private Sub _
            btn_Cancel_Click(sender As System.Object, _
                             e As System.EventArgs) _
                             Handles btn_Cancel.Click
    
            ' If the user chooses to cancel, just close the
            ' form. In Form1 (the calling form) we can detect
            ' that they've cancelled it because the
            ' "UserCancel" property defaults to True.
    
            Close()
    
        End Sub
    
        Public ReadOnly Property OptionSelected As OptionType
            Get
                Return _optionSelected
            End Get
        End Property
    
        Public ReadOnly Property UserCancel As Boolean
            Get
                Return _userCancel
            End Get
        End Property
    End Class

    Like I said last night, I might be completely off-base here but maybe this will give you some ideas.


    "A problem well stated is a problem half solved.” - Charles F. Kettering


    • Edited by Frank L. Smith Thursday, August 3, 2017 8:12 PM ...reworded
    Thursday, August 3, 2017 12:54 PM
  • Viorel

    I like either option you suggest. However when I try to utilize the code and build it  I get Code BC30451 Errors stating RadioButtonNCXX is not declared. It may be inaccessible due to its protection level.

    Here's  the code with your suggestions below.


    Public Class Form_Select_Machine


        Private Sub Form_Select_Machine_Load() Handles MyBase.Load

        End Sub

        Private Sub RadioButtonNC73_CheckedChanged(sender As Object, e As EventArgs) Handles RadioButton1.CheckedChanged
            'Writes NC73 to NC.txt file
            My.Computer.FileSystem.WriteAllBytes("C:\GEOMeasure\Traceability\NC.txt", System.Text.ASCIIEncoding.ASCII.GetBytes("NC73"), False)
            'MessageBox.Show(b.Length.ToString)
        End Sub

        Private Sub RadioButtonNC74_CheckedChanged(sender As Object, e As EventArgs) Handles RadioButton2.CheckedChanged
            'Writes NC74 to NC.txt file
            My.Computer.FileSystem.WriteAllBytes("C:\GEOMeasure\Traceability\NC.txt", System.Text.ASCIIEncoding.ASCII.GetBytes("NC74"), False)
        End Sub


        Private Sub RadioButtonNC81_CheckedChanged(sender As Object, e As EventArgs) Handles RadioButton3.CheckedChanged
            'Writes NC81 to NC.txt file
            My.Computer.FileSystem.WriteAllBytes("C:\GEOMeasure\Traceability\NC.txt", System.Text.ASCIIEncoding.ASCII.GetBytes("NC81"), False)
        End Sub


        Private Sub ButtonOK_Click(sender As Object, e As EventArgs) Handles ButtonOK.Click
            ' Close the form
            If Not RadioButtonNC73.Checked AndAlso Not RadioButtonNC74.Checked AndAlso Not RadioButtonNC81.Checked Then
                MsgBox("Please select an option")
                Return
            End If
            Close()
        End Sub

    End Class

    How do I declare a RadioButton to make this work?

    Saturday, August 5, 2017 5:05 PM
  • In this case, use the new names of checkboxes: RadioButton1, RadioButton2 and RadioButton3 instead of RadioButtonNCxx inside ButtonOK_Click.
    Saturday, August 5, 2017 5:13 PM
  • Thanks Viorel

    I had added a 4th RadioButton for Unaddressed with a default to be checked and hid the button and this worked as well.

    I prefer your method. This is used to tag dimensional data from 3 different Numerical Controlled (NC) machining centers. If the data is  unaddressed I have no idea of which machine the data belongs to. This makes sure the operator has to read and select a machine each time instead of just clicking "OK" and going on.

    Thanks Again.

    Saturday, August 5, 2017 8:03 PM