Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way to databind a group of radiobuttons in WinForms

I'm currently working on databinding some of my existing Windows Forms, and I've ran into an issue figuring out the proper way of databinding a group of radiobutton controls within a group box.

My business object has an integer property which I want to databind against 4 radiobuttons (where each of them represents the values 0 - 3).

I'm currently binding against a presenter object which works as the binder between the form and the business object, and the way I've done it now is to have 4 separate properties which each binds against each of these values (I do use INotifyPropertyChanged, but not including that here):

Private int _propValue;

Public bool PropIsValue0 
{ 
  get { return _propValue == 0; }
  set
  {
    if (value) 
      _propValue = 0;
  }
}

Public bool PropIsValue1 { // As above, but with value == 1 }
Public bool PropIsValue2 { // As above, but with value == 2 }
Public bool PropIsValue3 { // As above, but with value == 3 }

And I then bind each of the radiobuttons to their respective property as above.

This does not seem right to me, so any advice are highly appreciated.

like image 216
Geir-Tore Lindsve Avatar asked Mar 23 '09 20:03

Geir-Tore Lindsve


People also ask

How do you group radio buttons in Windows form application?

You group radio buttons by drawing them inside a container such as a Panel control, a GroupBox control, or a form. All radio buttons that are added directly to a form become one group. To add separate groups, you must place them inside panels or group boxes.

How to bind Radio button in c#?

Set the tag name of your radio buttons to something that represents the value. Create a string setting, for example, OptionDuplicateFiles, and give it the default value of the tag name for your default radio button. To save your checked radio button: Settings.


2 Answers

Following is a generic RadioGroupBox implementation in the spirit of ArielBH's suggestion (some code borrowed from Jay Andrew Allen's RadioPanel). Just add RadioButtons to it, set their tags to different integers and bind to the 'Selected' property.

public class RadioGroupBox : GroupBox {     public event EventHandler SelectedChanged = delegate { };      int _selected;     public int Selected     {         get         {             return _selected;         }         set         {             int val = 0;             var radioButton = this.Controls.OfType<RadioButton>()                 .FirstOrDefault(radio =>                     radio.Tag != null                     && int.TryParse(radio.Tag.ToString(), out val) && val == value);              if (radioButton != null)             {                 radioButton.Checked = true;                 _selected = val;             }         }     }      protected override void OnControlAdded(ControlEventArgs e)     {         base.OnControlAdded(e);          var radioButton = e.Control as RadioButton;         if (radioButton != null)             radioButton.CheckedChanged += radioButton_CheckedChanged;     }      void radioButton_CheckedChanged(object sender, EventArgs e)     {         var radio = (RadioButton)sender;         int val = 0;         if (radio.Checked && radio.Tag != null               && int.TryParse(radio.Tag.ToString(), out val))         {             _selected = val;             SelectedChanged(this, new EventArgs());         }     } } 

Note that you can't bind to the 'Selected' property via the designer due to initialization order problems in InitializeComponent (the binding is performed before the radio buttons are initialized, so their tag is null in the first assignment). So just bind yourself like so:

    public Form1()     {         InitializeComponent();         //Assuming selected1 and selected2 are defined as integer application settings         radioGroup1.DataBindings.Add("Selected", Properties.Settings.Default, "selected1");         radioGroup2.DataBindings.Add("Selected", Properties.Settings.Default, "selected2");     } 
like image 62
Ohad Schneider Avatar answered Sep 26 '22 23:09

Ohad Schneider


I know this post is old but in my search for an answer for this same problem I came across this post and it didn't solve my problem. I ended up having a lightbulb go off randomly just a minute ago and wanted to share my solution.

I have three radio buttons in a group box. I'm using a List<> of a custom class object as the data source.

Class Object:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace BAL
{
class ProductItem
{

    // Global Variable to store the value of which radio button should be checked
    private int glbTaxStatus;
    // Public variable to set initial value passed from 
    // database query and get value to save to database
    public int TaxStatus
    {
        get { return glbTaxStatus; }
        set { glbTaxStatus = value; }
    }

    // Get/Set for 1st Radio button
    public bool Resale
    {
        // If the Global Variable = 1 return true, else return false
        get
        {
            if (glbTaxStatus.Equals(1))
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        // If the value being passed in = 1 set the Global Variable = 1, else do nothing
        set
        {
            if (value.Equals(true))
            {
                glbTaxStatus = 1;
            }
        }
    }

    // Get/Set for 2nd Radio button
    public bool NeverTax
    {
        // If the Global Variable = 2 return true, else return false
        get
        {
            if (glbTaxStatus.Equals(2))
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        // If the value being passed in = 2 set the Global Variable = 2, else do nothing
        set
        {
            if (value.Equals(true))
            {
                glbTaxStatus = 2;
            }
        }
    }

    // Get/Set for 3rd Radio button
    public bool AlwaysTax
    {
        // If the Global Variable = 3 return true, else return false
        get
        {
            if (glbTaxStatus.Equals(3))
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        // If the value being passed in = 3 set the Global Variable = 3, else do nothing
        set
        {
            if (value.Equals(true))
            {
                glbTaxStatus = 3;
            }
        }
    }

// More code ...

Three seperate public variables with get/set accessing the same one global variable.

In the code behind, I have a function called during the Page_Load() setting all the controls databindings. For each radio button I add its own databinging.

radResale.DataBindings.Add("Checked", glbProductList, "Resale", true, DataSourceUpdateMode.OnPropertyChanged, false);
radNeverTax.DataBindings.Add("Checked", glbProductList, "NeverTax", true, DataSourceUpdateMode.OnPropertyChanged, false);
radAlwaysTax.DataBindings.Add("Checked", glbProductList, "Always", true, DataSourceUpdateMode.OnPropertyChanged, false);

I hope this helps someone!!

like image 38
Paul - SGS PfINDE Avatar answered Sep 23 '22 23:09

Paul - SGS PfINDE