0

so i had some wonderful help with the previous iteration of this that worked great!

I have tried modifying my code with the info at Get property value from string using reflection in C#

but either i am getting it wrong or my class is setup in a way as to not work with that method.

i used the code

foreach (var checkbox in this.Controls.OfType<CheckBox>())
        {
            pdfFormFields.SetField(checkbox.Name, checkbox.Checked ? "Yes" : "No");
        }

and it worked great now ive been told to use a class to make it more universtal my class is

public class Entries
{
    ///Some other Values
    public string ColourW;
    public bool CheckBox1 { get; set; }
    public bool CheckBox2 { get; set; }
    public bool CheckBox3 { get; set; }
    public bool CheckBox4 { get; set; }
    public bool CheckBox5 { get; set; }
    public bool CheckBox6 { get; set; }
    public bool CheckBox7 { get; set; }
    public bool CheckBox8 { get; set; }
    public bool CheckBox9 { get; set; }
}

I need a foreach statement like the above but to set the info to the data in class something like this, however i get a identifier expected error.

foreach (var checkbox in this.Controls.OfType<CheckBox>())
        {
            Data.(checkbox.Name, checkbox.Checked ? "Yes" : "No");
        }

Help is appreciated, help with an explanation of how the code work is greatly appreciated!

sorry in advance, Im a hardware guy!

EDIT

So solved majority of the issues thanks to @Furkan Kambay managed to get check-boxes into and out of class but for some reason the check-boxes on the PDF will not set to the same state?

Longer explanation, class is set up form works fine all combo boxes and text fields when called pdfFormFileds("Textx", Entries.ColourW); work fine however the PDF check boxes do not change state when using the code, i am using iTextSharp library

foreach (var box in Entries.CheckBoxes) 
            {
                pdfFormFields.SetField(box.Key, box.Value ? "Yes" : "No");
             }

Setup for PDF

string pdfTemplate = @"C:\Testing Templates\Pre V-Change Head Test Certificate Template.pdf";
            string newFile = @"c:\temp\PDF\" + Entries.SerialNumber + " " + Entries.TestedWithCal + " Pre V-Change Head Test Certificate.pdf";
            string Created;

            PdfReader pdfReader = new PdfReader(pdfTemplate);
            PdfStamper pdfStamper = new PdfStamper(pdfReader, new FileStream(newFile, FileMode.Create));
            AcroFields pdfFormFields = pdfStamper.AcroFields;
Rhys Clarke
  • 77
  • 12
  • So the checkbox.Name will be like "CheckBox1"/2/3 etc. and you want to find the variable with that name in your class and assign it to true or false, am I on the right path? – Furkan Kambay Jan 20 '18 at 00:37
  • thats exactly it! Checkbox1 on form needs to set Chekbox1 in class to the same state – Rhys Clarke Jan 20 '18 at 00:45
  • could be yes, but i dont want to use reflection if possible. like i said im a hardware guy and couldn't make heads or tails of the – Rhys Clarke Jan 20 '18 at 00:48
  • Are the names always going to stay the same? – Furkan Kambay Jan 20 '18 at 00:49
  • It will always be checkbox1 - checkbox1 etc – Rhys Clarke Jan 20 '18 at 00:50
  • Can you elaborate on that last issue? I have no idea what that means. What library are you using for PDF? (What type is `pdfFormFields`?) – Furkan Kambay Jan 20 '18 at 02:18
  • That's just a problem with the values "Yes" and "No". It takes something else like on off. So my answer did solve the problem, that's another and minor one, you can mark again. Check this out : https://stackoverflow.com/a/19707410/4187549 – Furkan Kambay Jan 20 '18 at 02:31

2 Answers2

1

Edit your class to be like this:

public static class Entries
{
    // ... all the other fields with static keyword
    public static string ColourLRB;
    public static string ColourW;
    public static Dictionary<string, bool> CheckBoxes { get; } = new Dictionary<string, bool>(); // no set, so you can only modify this. 
}

And then:

foreach (var checkbox in this.Controls.OfType<CheckBox>())
{
    CheckBoxes[checkbox.Name] = checkbox.Checked;
}

I think you can improve the foreach statement with a LINQ query mapping CheckBoxes to KeyValuePairs. If you want, I can edit the answer.

edit, mapping with LINQ: (replaces the whole foreach)

var boxes = this.Controls.OfType<CheckBox>();
CheckBoxes = boxes.ToDictionary(b => b.Name, b => b.Checked);

edit2, setting again

foreach(var box in Entries.CheckBoxes) // this is using static. For Singleton it would be "var box in Entries.Instance.CheckBoxes"
{
    pdfFormFields.SetField(box.Key, box.Value ? "Yes" : "No");
}
Furkan Kambay
  • 751
  • 1
  • 7
  • 18
  • Please go ahead – Rhys Clarke Jan 20 '18 at 01:12
  • the class file is separate to form code, Dictionary has error when placed into form stating it requires 2 arguments. Also i need to pass Entries to a subroutine on another form can i do this and keep it static? – Rhys Clarke Jan 20 '18 at 01:19
  • @RhysClarke You don't have to mess with the form. Just the Entries class. Just modify the Entries class as I did in this answer. You can't put a dictionary in a form anyway. – Furkan Kambay Jan 20 '18 at 01:23
  • For the static thing, you can make it a Singleton. Google it. – Furkan Kambay Jan 20 '18 at 01:23
  • @RhysClarke Did you solve the problem? I gave you 3 valid answers. The answer should be 3 letters long, starting with 'y', ending with 's' and also containing 'e'. – Furkan Kambay Jan 20 '18 at 01:34
  • ok that gets them in but how about out again e.g. need to run pdfFormFields.SetFiel("CheckBox1/2/3/n", Entries.checkbox1/2/3/n); Also i just wanted to say thanks sooooo much for your help its really nice to see that people in this word are still willing to help each other out, answer marked! – Rhys Clarke Jan 20 '18 at 01:39
  • @RhysClarke Added that to the answer. Yep, you're welcome! – Furkan Kambay Jan 20 '18 at 01:44
  • box.Value cant convert bool to string – Rhys Clarke Jan 20 '18 at 01:48
  • @RhysClarke Yeah that edit is correct. Sorry, wasn't using an editor/IDE. And about the bool to string, corrected that, too. – Furkan Kambay Jan 20 '18 at 01:49
  • hmm no, checkboxes dont check the pdf – Rhys Clarke Jan 20 '18 at 02:03
  • But you marked answer, you should revert it until it's solved. What's the problem now? You should edit the question, we added too many comments. – Furkan Kambay Jan 20 '18 at 02:07
  • I have stopped using the LINQ and am using the foreach statment, works fine! marked as answer! – Rhys Clarke Jan 20 '18 at 12:27
0
var entries = new Entries(); // looks to me like this class and its members should be static, no?
foreach (var checkbox in this.Controls.OfType<CheckBox>())
{
    if(checkbox.Name == "CheckBox1") entries.CheckBox1 = checkbox.Checked;
    else if(checkbox.Name == "CheckBox2") entries.CheckBox2 = checkbox.Checked;
    else if(checkbox.Name == "CheckBox3") entries.CheckBox3 = checkbox.Checked;
    // ...
}
Furkan Kambay
  • 751
  • 1
  • 7
  • 18
  • this works, but i can already set them like this. I suppose my additional question is can i do it without referring to each box? what do you mean by static? – Rhys Clarke Jan 20 '18 at 00:59
  • Well the other way is using reflection. You could replace all the properties with a single `Dictionary` and do `dictionary[checkbox.Name] = checkbox.Checked` in foreach. – Furkan Kambay Jan 20 '18 at 01:01
  • By static I mean if you don't need multiple instances of the Entities class, you should make it `static` so you can access its members like this: `Entities.CheckBox1` – Furkan Kambay Jan 20 '18 at 01:03
  • can you show me how to use reflections, and that is true. – Rhys Clarke Jan 20 '18 at 01:03
  • @RhysClarke I already provided the reflection solution, it's the link on your question. I submitted another answer with the dictionary solution. – Furkan Kambay Jan 20 '18 at 01:11