common DataBinding scenario: Yes/No backed by true/false

S

sklett

I have the need to display a DropDown with 2 options: Yes/No.
I want to bind this control to an entity which represents the field in
question with a bool.

What I've done in the interim is to manually add "YES" and "NO" strings to
the control, then in the SelectedIndexChanged event set the bool value by
performing a string comparison for YES or NO. This is less than elegant.

I've been thinking of way to set the DataSource of the DropDown that would
allow me to bind straight to the SelectedValue property. The only thing I
can come up with is to create a small class like:
class YesNoOption
{
private string _display;
private bool _value;
public YesNoOption(string display, bool value)
{
_value = value;
_display = display;
}

// properties
}

Then create 2 of the above and place in a List.

List<YesNoOption> options = new List<YesNoOption>();
options.Add(new YesNoOption("YES", true));
options.Add(new YesNoOption("NO", false));

comboBoxBindingSource.DataSource = options;

There must be a better way than all of this, no? This seems like a common
scenario that people would deal with but I haven't been able to find much on
the topic.

Any suggestions or experiences with this scenario?

Thanks,
Steve
 
M

Marc Gravell

You can do this very cleanly using a TypeConverter; if you can wait a
few hours, I'll knock something together tomorrow? (tight for time
right now)

Marc
 
S

Steve K.

Marc Gravell said:
You can do this very cleanly using a TypeConverter; if you can wait a
few hours, I'll knock something together tomorrow? (tight for time
right now)

Marc

Marc, that would be cool. This is a LOW priority for me, so I can certainly
wait a few days. Thanks for the offer.

-Steve
 
M

Marc Gravell

Well, what I /wanted/ to do turned out messier than I planned, since the
solution I was thinking of applies mainly to an "I'll show/bind anything"
control I have locally, but how about the following C# 3 solution (the main
bit being the anonymous type/array, marked "KEY BIT")?

Marc

static class Program {
static void Main() {
// our demo object
Foo foo = new Foo();

Application.EnableVisualStyles();
using (Form form = new Form {
Controls = {
new CheckBox {
Dock = DockStyle.Top,
DataBindings = {
{ "Checked", foo, "Bar", false,
DataSourceUpdateMode.OnPropertyChanged }
}
},
new ComboBox {
Dock = DockStyle.Top,
DropDownStyle = ComboBoxStyle.DropDownList,
// *** START KEY BIT
ValueMember = "Value",
DisplayMember = "Text",
DataSource = new[] {
new {Text="Yes", Value=true},
new {Text="No", Value=false}
},
DataBindings = {
{"SelectedValue", foo, "Bar",false,
DataSourceUpdateMode.OnPropertyChanged}
}
// *** END KEY BIT
}
}

}) {
foo.PropertyChanged += delegate {
form.Text = string.Format("Bar={0}", foo.Bar);
};

Application.Run(form);
}
}
}
public class Foo : INotifyPropertyChanged {
private bool bar;
public bool Bar {
get { return bar; }
set {UpdateField(ref bar, value, "Bar");}
}
protected void UpdateField<T>(ref T field, T value, string propertyName)
{
// general purpose "if changed, update field and notify" method
if (!EqualityComparer<T>.Default.Equals(field, value)) {
field = value;
if (PropertyChanged != null) PropertyChanged(this, new
PropertyChangedEventArgs(propertyName));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
 
R

RobinS

With textboxes, you can add event handlers to the Format and Parse events
for the binding, and do this kind of thing that way. Hopefully the same
thing would work with comboboxes.

It basically lets you capture the data when flowing between the data source
and the control, and changing it or translating it in each direction.

The Format event is fired when moving data from the data source to the
control (you substitute "YES" for true). The Parse event is fired when
moving data from the control to the data source (you substitute true for
"YES").

I can post code for doing this with a textbox; let me know if you need it.

RobinS.
GoldMail, Inc.
 
S

sklett

Hi Marc,

This slipped by me somehow, I've only just seen your response. I will check
this out later and get back to you.

Thanks for taking the time!
-Steve
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top