Jawab Radio Button Behavior

  • Monday, April 30, 2012 9:08 PM
     
      Has Code

    I can't figure out how to get "normal" Radio Button Behavior. Where there is a group of Properties and always just one of them must always be true.

    I'm actually using Check Boxes as those are the default for a Boolean Property. And the code from the solution here. It doesn't matter to me which control is used. I couldn't figure out how to do this using the actual Radio Button control either.

    So if I check a box in the group to be true, the others go to false. But I can still uncheck the checked box and then have none of the boxes in the group be true.

    I would like for one Property to always be true.

    I tried code like this, but got a Stack Overflow error:

            Private Sub MSSelect_Validate()
                'Ensure that one option is always selected
                If ((MSSelect = False) And
                    (FindControl("SS304Select").IsVisible = True)) Then
                    SS304Select = True
                ElseIf ((MSSelect = False) And
                    (FindControl("SS316Select").IsVisible = True)) Then
                    SS316Select = True
                Else
                    MSSelect = True
                End If
            End Sub
    I hope I explained that well enough. Let me know if it is not clear. Thanks.


All Replies

  • Tuesday, May 01, 2012 8:18 AM
     
     

    It is not usually a good idea to try to make check-boxes work like radio buttons. They serve different purposes and you risk confusing the users if they see one used as the other.

    As LightSwitch doesn't include radio button controls the best fit would be an AutoCompleteBox.

    You probably get a stack overflow error because your code goes into a tight loop as changing one value causes another one to change which causes another change and eventually changes the first control again which causes the whole cycle to start again. If you want to avoid this, set a boolean module level variable at the start of your validation code and use that to signal that you should ignore any changes. Reset this module level variable to false at the end of your processing. This way changes are processed that come from the user but ignored when they come from your code.


    Simon Jones
    If you found this post helpful, please "Vote as Helpful". If it actually answered your question, please remember to "Mark as Answer". This will help other people find answers to their problems more quickly.

  • Tuesday, May 01, 2012 12:45 PM
     
     

    I've read a lot of threads saying that Lightswitch does not contain Radio Buttons. I don't understand this. Radio Buttons are easily selectable under Custom Controls. I just can't figure out how to link individual Radio Buttons together into a group to get the proper behavior. There are no easily selectable options to do so.

    So I assume it will take some custom code which is fine. I will play around with your suggestion of creating a module level variable to help control the behavior.

    I agree with you that an AutoCompleteBox would be a better solution to this problem. However, I'm trying to update an old Access based sales application into a web based, SQL backed app as the Access app has reached some of it's limits. Lightswitch seems designed for exactly this purpose. One of the requirements is to keep the look as similar to the old app as possible to avoid as much retraining as possible. The old app used the Radio Button behavior extensively so I would like to have an easy way to implement it to keep the look and feel as close to the old app as possible while adding the benefits of web hosting and an SQL database.

  • Tuesday, May 01, 2012 1:04 PM
     
     Answered

    You have to buy or write some (wrapper) code in order to use other, Custom, Silverlight controls easily with LightSwitch.

    Silverlight RadioButtons have a GroupName property which can be used to tie several RadioButtons together into a multually exclusive group. You would probably have to programmatically set this GroupName property in the ControlAvailable events for all the RadioButton controls you use on a form.

    Boolean (bit) fields map naturally onto Check Boxes - Each field is naturally independent of the others.

    A set (group) of Radio Buttons is the more natural expression of an Integer or String field that can take ONE of a SMALL range of different values. (Hence a group of radio buttons is usually replaced by an AutoCompleteBox if radio buttons are not available, space on the form is limited or the range of possible values grows to be too large.)

    If your database design has a set of bit fields that are/should be mutually exclusive then your database design is probably wrong.


    Simon Jones
    If you found this post helpful, please "Vote as Helpful". If it actually answered your question, please remember to "Mark as Answer". This will help other people find answers to their problems more quickly.

    • Marked As Answer by kyle ls Tuesday, May 01, 2012 6:13 PM
    •  
  • Tuesday, May 01, 2012 1:37 PM
     
     

    The GroupName property sounds like what I'm looking for. How do I access that?

    I've found GroupDescription and MyGroupCollectionAttribute classes that I'm going to go read up on to see if those are what I need.

    I don't believe my database has mutually exclusive bit fields, but let me give you an example. The old Access tables are a mess and completely useless. So I'm rewriting the database almost from scratch and would like to get it into the most correct and useful form possible.

    The rows of the database are individual products identified by a unique model number. The columns are all the options available. If an option is available for a product, the cell contains a part number that is tied to a separate table containing prices. If it is not available, it contains a NULL.

    For instance, there is a column for Mild Steel, another for Stainless 304 and another for Stainless 316. The previous program had a Radio Button for each construction option and the user could only select one out of the available options. The program would then read the true/false status of each button, grab the part number for the single true choice, and write the corresponding price to a table to be tabulated later. That is what I'm trying to emulate.

    Does this sound like a valid database design? If not, suggestions for improving it are most welcome.

  • Tuesday, May 01, 2012 2:27 PM
     
     

    I would guess that In the ControlAvailable event for each control you would cast (CType) the control to a RadioButton and then you will be able to access the property.

    The columns for the part numbers for Mild Steel, Stainless 304 and Stainless 316 materials are a repeating group and should (according to database design principles) be moved into a separate table which would have the ProductID, MaterialID and PartNumber. This could possibly be an extension of the Prices table depending on what else was in that table.

    The reason for this change is what happens if a new material is introduced (EG Titanium). Your current database design would have to be changed to introduce a new column for that material and your front end would have to be changed to accomodate.

    In the design I outlined above the Material is just a piece of data and you can add new Materials whenever you want to with no change to the database or the front-end.

    In a LightSwitch application you would see a grid of Products and selecting one product would show the Materials and PartNumbers (and Prices) in which the selected Product was available in a separate grid.


    Simon Jones
    If you found this post helpful, please "Vote as Helpful". If it actually answered your question, please remember to "Mark as Answer". This will help other people find answers to their problems more quickly.

  • Tuesday, May 01, 2012 3:05 PM
     
     

    I'm making a Radio Button extension which you will be able to replace an AutoCompleteBox with.  It will give radio button options instead of a drop down box.

    Keep an eye here:
    http://visualstudiogallery.msdn.microsoft.com/bbe013bf-45b6-46c4-ba13-537cc23c5118
    it should be released soon (free).  I just need to finish testing it, then backporting it to old Lightswitch (I've developed the extension on the new version of LS, but it should work with both).

  • Tuesday, May 01, 2012 3:24 PM
     
     Answered

    Take a look at this article.  I converts a Checkbox to a multiple choice radiobutton.  Not exactly what your looking for but it might provide some insight.

    • Marked As Answer by kyle ls Tuesday, May 01, 2012 6:13 PM
    •  
  • Tuesday, May 01, 2012 3:29 PM
     
     

    @Simon Jones - Okay I've gotten access to the GroupName property via ControlAvailable. I'll play around with that and see if it does what I'm looking for.

    I've thought I needed a separate table for the options. For just the reasons you've outlined. I just haven't been able to think of a way to represent everything I need.

    I'm having some trouble wrapping my head around your example. What would be the primary key? And how would I represent which Product has which Materials available?


    • Edited by kyle ls Tuesday, May 01, 2012 3:38 PM Reference user
    •  
  • Tuesday, May 01, 2012 3:31 PM
     
     
    @ElyIV - I look forward to it as I'd like an easy way to drop Radio Buttons in. In the meantime, learning inner working of Lightswitch is helpful in it's own way.


    • Edited by kyle ls Tuesday, May 01, 2012 3:39 PM Reference user
    •  
  • Tuesday, May 01, 2012 4:12 PM
     
     

    Products
    PK  ProductID
          Description
          ...(any other fields you need)

    Materials
    PK  MaterialID
          Description
          ...(any other fields such as Withdrawn or DisplayOrder)

    ProductsMaterials
    PK   ProductMaterialID
    FK1 ProductID
    FK2 MaterialID
          PartNumber
          ...(you could have the Price here or other fields if necessary)

    The fact that a product is available in a particular material is indicated by a record in the ProductsMaterials table.

    Note that your Materials table should contain a Withdrawn flag if you want to retain rows in ProductsMaterials when a Material is "discontinued". You'd filter the query used for the AutoCompleteBox on the form to exclude Withdrawn items so users can't choose that Material once it has been Withdrawn. Alternatively you can set the relationship (FK2) to cascade deletes so deleting a Material will delete all the ProductsMaterials records associated to that Material. (If you don't set this cascade you would get an error on attempting to delete a Material that had been used.)


    Simon Jones
    If you found this post helpful, please "Vote as Helpful". If it actually answered your question, please remember to "Mark as Answer". This will help other people find answers to their problems more quickly.

  • Tuesday, May 01, 2012 4:16 PM
     
     
    Oh, you might also have a unique index on the ProductsMaterials table containin the ProductID and MaterialID columns so that you can only have one record for each combination of Product and Material. (You could also add validation in LightSwitch for this to avoid getting a database error when saving a duplicate.)

    Simon Jones
    If you found this post helpful, please "Vote as Helpful". If it actually answered your question, please remember to "Mark as Answer". This will help other people find answers to their problems more quickly.

  • Tuesday, May 01, 2012 6:13 PM
     
     

    I have tested out the suggested code and both @Simon Jones and @Dave Vorgang have provide correct answers to the initial question. I will have to make some modifications to my database to bring it inline with @Simon Jones' suggestions. That should provide the functionality I am looking for. Then I will have to play with both solutions some more to see which is a better fit.

    Thanks guys!