Reputation: 51
Is there a way I can add Values to a List by iterating? I have a form with all the variables declared and a class to collect all the information. But I'm trying to learn a way to add all this through code instead of having so much repeated code.
namespace WinForm
{
public partial class Form_Destrezas : Form
{
//Fields
Tab_Destreza Personales;
Tab_Destreza Salud;
Tab_Destreza Participacion;
Tab_Destreza Convivencia;
Tab_Destreza Limpieza;
Tab_Destreza Alimentos;
Tab_Destreza Ropa;
Tab_Destreza Libre;
Tab_Destreza Futuro;
public Form_Destrezas()
{
Personales.AddRow(Personales_1RowNoApp,
Personales_1RowNoDom,
Personales_1RowEnPro,
Personales_1RowDomina,
Personales_1RowCheckBox)
//What I want to do
for (int i = 0; i <= 10; i++)
{
Personales.AddRow(Personales_[i]RowNoApp,
Personales_[i]RowNoDom,
Personales_[i]RowEnPro,
Personales_[i]RowDomina,
Personales_[i]RowCheckBox)
}
this.Text = $"Destrezas - {StudentData.Name}";
InitializeComponent();
}
private void Personales_1RowNoDom_CheckedChanged(object sender, EventArgs e)
{
Personales.checkRow();
}
}
/// <summary>
/// Data for each row will be collected here.
/// </summary>
public class RowData
{
//Fields
public List<RadioButton> RadioButtons;
public CheckBox TeacherVerified;
public string ActiveStatus = "No Applica";
public bool verified = false;
//Methods
/// <summary>
/// Input row information collection.
/// </summary>
/// <param name="noApp">Radiobutton "No Applica" for Row.</param>
/// <param name="noDom">Radiobutton "No Domina" for Row.</param>
/// <param name="enProc">Radiobutton "En Processo" for Row.</param>
/// <param name="domina">Radiobutton "Domina" for Row.</param>
/// <param name="EviMaestro">CheckBox if was verified.</param>
public void AddRow(RadioButton noApp, RadioButton noDom, RadioButton enProc,
RadioButton domina, CheckBox EviMaestro)
{
var personalesRows = this.GetType().GetTypeInfo();
RadioButtons.Add(noApp);
RadioButtons.Add(noDom);
RadioButtons.Add(enProc);
RadioButtons.Add(domina);
TeacherVerified = EviMaestro;
checkRow();
}
/// <summary>
/// Collects Data from row.
/// </summary>
public void checkRow()
{
foreach (var Button in RadioButtons)
{
if (Button.Checked)
{
ActiveStatus = Button.Text;
}
}
if (TeacherVerified.Checked == true)
{
verified = TeacherVerified.Checked;
}
}
}
public class Tab_Destreza : RowData
{
}
}
Upvotes: 1
Views: 164
Reputation: 64943
First of all I would build a sequence on which each element would be a map of each row's class field name and their corresponding values:
var personalesRowMaps = this.GetType().GetTypeInfo().GetFields(BindingFlags.Instance | BindingFlags.NonPublic)
.Where(f => f.Name.StartsWith("Personales_"))
// f.Name.Split(...) part explained: each field has an underscore,
// where the next character after it is the row index. Thus,
// I split the name using the underscore and I get the right part
// of the field identifier, and then I get the first character of
// that part: the row index.
.Select(f => new { Index = f.Name.Split('_')[1][0], Field = f })
.GroupBy(o => o.Index)
.Select(g => g.ToList().ToDictionary(o => o.Field.Name, o => o.Field.GetValue(this)));
Step by step:
class
."Personales_"
prefix.Once you've built that map, adding the whole rows is an easy task. You just need to iterate each dictionary and add each field to Personales
, where the row index will be the index of the for
loop:
for(int i = 0; i < personalRowMaps.Count; i++)
{
var rowMap = personalRowMaps[i];
Personales.AddRow
(
rowMap[$"Personales_{i}RowNoApp"],
rowMap[$"Personales_{i}RowNoDom"],
rowMap[$"Personales_{i}RowEnPro"],
rowMap[$"Personales_{i}RowDomina"],
rowMap[$"Personales_{i}RowCheckBox"]
);
}
Notes:
private
, protected
or public
. For now, I'll think that they're private
(see the binding flags on the LINQ query). Please comment out what access modifier have these class fields.object
...
THE OP HAS ALREADY PROVIDED THE REQUIRED INFO!Upvotes: 1