patterncsharpMinor
Ideas for reducing repetition in control binding
Viewed 0 times
controlreducingforideasrepetitionbinding
Problem
I have seven checkboxes on a data maintenance WinForm, which indicate the days of the week that are "valid" for a particular operation to be performed. These "map" to a list of DayOfWeek enum values on the backing domain object; if the value is present in the list, the box should be checked, otherwise not. Any combination of boxes can be checked. In the "bind" method that sets the UI controls to the proper values of the domain object, here's how those checkboxes are set:
The code to read the UI controls' state back out to the domain object is similar; if the box is checked, add the corresponding value to a "clean" (initially empty) list and assign it to the object.
This smells. I was thinking of adding a Dictionary containing the checkboxes and keyed to their corresponding DayOfWeek. But, that sounds like a bit much as well (it certainly wouldn't save many LoC). Any other suggestions?
chkValidDayMon.Checked = myModel.ValidDaysOfWeek.Contains(DayOfWeek.Monday);
chkValidDayTue.Checked = myModel.ValidDaysOfWeek.Contains(DayOfWeek.Tuesday);
chkValidDayWed.Checked = myModel.ValidDaysOfWeek.Contains(DayOfWeek.Wednesday);
chkValidDayThu.Checked = myModel.ValidDaysOfWeek.Contains(DayOfWeek.Thursday);
chkValidDayFri.Checked = myModel.ValidDaysOfWeek.Contains(DayOfWeek.Friday);
chkValidDaySat.Checked = myModel.ValidDaysOfWeek.Contains(DayOfWeek.Saturday);
chkValidDaySun.Checked = myModel.ValidDaysOfWeek.Contains(DayOfWeek.Sunday);The code to read the UI controls' state back out to the domain object is similar; if the box is checked, add the corresponding value to a "clean" (initially empty) list and assign it to the object.
This smells. I was thinking of adding a Dictionary containing the checkboxes and keyed to their corresponding DayOfWeek. But, that sounds like a bit much as well (it certainly wouldn't save many LoC). Any other suggestions?
Solution
I'd create an extension method that calculates the day by the name of the checkbox.
I'm using dynamic because I don't know the name of your domain class, just replace it with your name.
Also note, I'm using the web version of CheckBox, substitute ID with whatever version you are using.
Here is the class for the extension:
Then your calls would be
Another thing you might look into is to put the CheckBox objects into a list, then you could just iterate it:
Another note, Hungarian casing on variables is not really accepted anymore. It clutters up the code, and there are too many variable types to abbreviate them all to 3 letters. Read this. A better naming convention would be mondayIsValidCheckBox. You would have to modify my extension method to use this new convention.
I'm using dynamic because I don't know the name of your domain class, just replace it with your name.
Also note, I'm using the web version of CheckBox, substitute ID with whatever version you are using.
Here is the class for the extension:
public static class CheckboxExtensions
{
public static void DetermineStateFromModel(this CheckBox me, dynamic myModel)
{
if (!me.ID.Contains("chkValidDay"))
{
// Could throw an exception if required.
return;
}
var dayOfWeek = DayOfWeekFromString(me.ID.Replace("chkValidDay", string.Empty));
me.Checked = myModel.ValidDaysOfWeek.Contains(dayOfWeek);
}
private static DayOfWeek DayOfWeekFromString(string dayOfWeek)
{
switch (dayOfWeek)
{
case "Mon":
return DayOfWeek.Monday;
case "Tue":
return DayOfWeek.Tuesday;
// ...
default:
throw new ApplicationException("Invalid dayOfWeek specified.");
}
}
}Then your calls would be
chkValidDayMon.DetermineStateFromModel(myModel);
chkValidDayTues.DetermineStateFromModel(myModel);
...Another thing you might look into is to put the CheckBox objects into a list, then you could just iterate it:
dayCheckBoxList.ForEach(checkBox => checkBox.DetermineStateFromModel(myModel));Another note, Hungarian casing on variables is not really accepted anymore. It clutters up the code, and there are too many variable types to abbreviate them all to 3 letters. Read this. A better naming convention would be mondayIsValidCheckBox. You would have to modify my extension method to use this new convention.
Code Snippets
public static class CheckboxExtensions
{
public static void DetermineStateFromModel(this CheckBox me, dynamic myModel)
{
if (!me.ID.Contains("chkValidDay"))
{
// Could throw an exception if required.
return;
}
var dayOfWeek = DayOfWeekFromString(me.ID.Replace("chkValidDay", string.Empty));
me.Checked = myModel.ValidDaysOfWeek.Contains(dayOfWeek);
}
private static DayOfWeek DayOfWeekFromString(string dayOfWeek)
{
switch (dayOfWeek)
{
case "Mon":
return DayOfWeek.Monday;
case "Tue":
return DayOfWeek.Tuesday;
// ...
default:
throw new ApplicationException("Invalid dayOfWeek specified.");
}
}
}chkValidDayMon.DetermineStateFromModel(myModel);
chkValidDayTues.DetermineStateFromModel(myModel);
...dayCheckBoxList.ForEach(checkBox => checkBox.DetermineStateFromModel(myModel));Context
StackExchange Code Review Q#14948, answer score: 2
Revisions (0)
No revisions yet.