This function takes inputs from multiple different controls on a form, and maps them to values in a data accumulation class. This code was written specifically to keep logic, data, and display separated. I ended up at the time using reflection to take the values from the controls and mapping them to variables with the same names in the accumulation class. The reasoning behind doing it this way was I didn't want a bunch of:
variable = control.value
Calls being repeated throughout this section of code, and should it end up that I needed additional controls on that form, I wanted to be able to just add the appropriate variable to the accumulation class and let the program handle adding that information to the accumulator dynamically.
I'm posting here to see what if any better ways to do this exist. (I'm sure there must be one, but this was the method I found that works.)
What I've written works well, and does it's job, but feels like very very bad code.
This is the mapping method:
/// <summary>
/// Updates the random accumulator. One method to rule *ALL* The random controls!
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void UpdateRandomAccumulator ( object sender, EventArgs e ) {
//Dear Future Me: You are a genius. You made this work. Despite overwhelming odds, you are victorious!
//Be proud future me, when you look upon this method in total confusion, since you probably forgot
//*exactly how* it works 10 minutes after closing this class.
Control control = sender as Control;
if ( control is TrackBar ) {
TrackBar tbar = control as TrackBar;
string controlName = control.Name.Remove ( 0, 9 );
//okay limiting our MinBads/MaxTourists here.
if ( controlName.Equals ( "MinNumberOfBadasses" ) || controlName.Equals ( "MaxNumberOfTourists" ) ) {
if ( tbar.Value >= randAccum.NumberToCreate ) {
tbar.Value = randAccum.NumberToCreate;
}
}
foreach ( var prop in randAccum.GetType( ).GetProperties( ) ) {
if ( controlName == prop.Name ) {
if ( prop.PropertyType == typeof(float) ) {
prop.SetValue ( randAccum, (float) tbar.Value / 100 );
}
else if ( prop.PropertyType == typeof(int) ) {
prop.SetValue ( randAccum, tbar.Value );
}
else {
Logger.LogEvent ( prop.PropertyType.ToString ( ) );
}
}
}
tbar_rnd_MaxNumberOfTourists.Maximum = randAccum.NumberToCreate;
tbar_rnd_MinNumberOfBadasses.Maximum = randAccum.NumberToCreate;
if ( tbar_rnd_MaxNumberOfTourists.Value > randAccum.NumberToCreate ) {
tbar_rnd_MaxNumberOfTourists.Value = randAccum.NumberToCreate;
}
if ( tbar_rnd_MinNumberOfBadasses.Value > randAccum.NumberToCreate ) {
tbar_rnd_MinNumberOfBadasses.Value = randAccum.NumberToCreate;
}
}
if ( control is CheckBox ) {
CheckBox cbox = control as CheckBox;
string controlName = cbox.Name.Remove ( 0, 8 );
//because use Ratio is notted, we have to set it by hand.
//The For loop is left incase we add any more checkboxes.
if ( controlName.Equals ( "useRatio" ) ) {
tbar_rnd_FtMRatio.Enabled = !cbox.Checked;
randAccum.useRatio = !cbox.Checked;
}
else {
foreach ( var prop in randAccum.GetType( ).GetProperties( ) ) {
if ( controlName == prop.Name ) {
if ( prop.PropertyType == typeof(bool) ) {
prop.SetValue ( randAccum, cbox.Checked );
}
}
}
}
}
randAccum.NumberToCreate = randAccum.Pilots + randAccum.Engineers + randAccum.Scientists;
UpdateRandomDisplay ( );
}
And here's the accumulation class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace KerbalTherapist.Accumulators {
public class RandomAccumulator {
//number of kerbals to create
public int NumberToCreate { get; set; }
public bool useRatio { get; set; }
public bool isKerman { get; set; }
//gendersettings;
public float FtMRatio { get; set; }
//ability scores
public float MinStupid { get; set; }
public float MaxStupid { get; set; }
public float MinBrave { get; set; }
public float MaxBrave { get; set; }
public int MinNumberOfBadasses { get; set; }
public int MaxNumberOfTourists { get; set; }
//Profession Ratios
public int Pilots { get; set; }
public int Engineers { get; set; }
public int Scientists { get; set; }
public RandomAccumulator ( ) {
NumberToCreate = 1;
FtMRatio = 0;
useRatio = true; //needs to be true by default.
MinStupid = 0.0f;
MaxStupid = 0.0f;
MinBrave = 0.0f;
MaxBrave = 0.0f;
MinNumberOfBadasses = 0;
MaxNumberOfTourists = 0;
Pilots = 0;
Engineers = 0;
Scientists = 0;
}
public RandomAccumulator Reset ( ) {
return new RandomAccumulator ( );
}
}
.NET
environment (Windows Forms, Web ASP.NET, WPF ..etc.), and an explanation on what you've experienced that led you to this code (what are you trying to achieve).? \$\endgroup\$