views:

446

answers:

1

I am following the "Presentation Model" design pattern suggested by Martin Fowler for my GUI architecture in a Windows Forms project.

"The essence of a Presentation Model is of a fully self-contained class that represents all the data and behavior of the UI window, but without any of the controls used to render that UI on the screen. A view then simply projects the state of the presentation model onto the glass...." - Martin Fowler

Read more about this pattern at www.martinfowler.com/eaaDev/PresentationModel.html

I am finding the concept very fluid and easy to understand except this one issue of data binding RadioButtons to properties on the Data/Domain object.

Suposing I have a Windows Form with 3 radio buttons to depict some "Mode" options as -

  • Auto
  • Manual
  • Import

How can I use boolean properties on Data/Domain Objects to DataBind to these buttons? I have tried many ways but to no avail. For example I would like to code like -

rbtnAutoMode.DataBindings.Add("Text", myBusinessObject, "IsAutoMode"); rbtnManualMode.DataBindings.Add("Text", myBusinessObject, "IsManualMode"); rbtnImportMode.DataBindings.Add("Text", myBusinessObject, "IsImportMode");

There should be a fourth property like "SelectedMode" on the data/domain object which at the end should depict a single value like "SelectedMode = Auto". I am trying to update this property when any of the "IsAutoMode", "IsManualMode" or "IsImportMode" is changed, e.g. through the property setters. I have INotifyPropertyChanged implemented on my data/domain object so, updating any data/domain object property automatically updates my UI controls, that's not an issue.

There is a good example of binding 2 radio buttons here - http://stackoverflow.com/questions/344964/how-do-i-use-databinding-with-windows-forms-radio-buttons

but I am missing the link while implementing the same with 3 buttons. I am having very erratic behaviors for the Radio Buttons.

I hope I was able to explain reasonably. I am actually in a hurry and could not put a detailed code on post, but any help in this regard is appreciated.

There is a simple solution to this issue by exposing a method like -

public void SetMode(Modes mode) { this._selectedMode = mode; }

which could be called from the "CheckedChanged" event of the Radio Buttons from the UI and would perfectly set the "SelectedMode" on the business object, but I need to stretch the limits to verify whether this can be done by DataBinding.

A: 

I am seeing that this question is getting good views but there's no answer posted yet. So I thought I should share what I finally did to solve this.

My Domain/Business Model class contains a "Mode" property which is of Type "string". For AUTO/MANUAL/IMPORT modes, the Mode property should contain "A"/"M"/"I" respectively. My domain model is received by my Presentation Model class through the constructor in the Presentation Model.

My Presentation Model class contains three boolean variables as "IsAutoMode", "IsManualMode", "IsImportMode". These boolean variables will be used for DataBinding the radio buttons on the Form. The GET/SET for these boolean properties are a little extended to handle updating the corresponding property ("Mode") in the domain model. Note the property GET/SET code in the presentation model class below -

    public bool IsAutoMode
    {
        get
        {
            return _domainModel.Mode.ToUpper() == "A";
        }
        set
        {
            _domainModel.Mode = (value == true) ? "A" : _domainModel.Mode;
        }
    }
    public bool IsManualMode
    {
        get
        {
            return _domainModel.Mode.ToUpper() == "M";
        }
        set
        {
            _domainModel.Mode = (value == true) ? "M" : _domainModel.Mode;
        }
    }
    public bool IsImportMode
    {
        get
        {
            return _domainModel.Mode.ToUpper() == "I";
        }
        set
        {
            _domainModel.Mode = (value == true) ? "I" : _domainModel.Mode;
        }
    }

Now, once these boolean properties are setup in your presentation model class, you can easily databind the radio button controls on your Form as below

rbtnAutoMode.DataBindings.Add("Checked", _pmodel, "IsAutoMode");
rbtnManualMode.DataBindings.Add("Checked", _pmodel, "IsManualMode");
rbtnImportMode.DataBindings.Add("Checked", _pmodel, "IsImportMode");

and see your radio button databinding fly. The current example stands valid irrespective of what type of property you want to hold in the domain model, be it a "string", "boolean", anything. The key point is to rely on -

get { return _domainModel.Mode.ToUpper() == <corresponding domain property val>; }

in the property GET rather than returning local field value and to NOT TO set any value in the domain model in case the "value" that comes in the property SET is not TRUE, else let the domain model have its current value

set { _domainModel.Mode = (value == true) ? <domain property to set> : _domainModel.Mode; }

Another important point is that this type of radiobutton databinding works only when the Binding.DataSourceUpdateMode is set to OnValidation which is the default. If changed to OnPropertyChanged the event firing sequence of the properties, when switching from one button to another button, behaves in a way that prevents evaluation of correct property value for the button to which the control is moving. But the DataSourceUpdateMode is hardly changed in normal applications and thus fortunately this will work for most applications with TWO or MORE radiobuttons.

Feel free to query further on this at [email protected]. Will be glad to help (if I can).

Rajarshi