PDFsharp & MigraDoc Foundation

PDFsharp - A .NET library for processing PDF & MigraDoc Foundation - Creating documents on the fly
It is currently Tue Mar 19, 2024 9:10 am

All times are UTC


Forum rules


Please read this before posting on this forum: Forum Rules



Post new topic Reply to topic  [ 11 posts ] 
Author Message
PostPosted: Wed Mar 29, 2017 4:33 pm 
Offline

Joined: Wed Mar 29, 2017 4:22 pm
Posts: 12
Location: Virginia (USA)
I'm filling in a premade PDF form and I've got the text fields working great.
I've run into an issue with the Radio Buttons though:

In my code it SEEMS to work in that if I set a SelectedIndex on my PdfRadioButtonField I can see the corresponding Value property in the Visual Studio.
Likewise if I set the Value property it changes the SelectedIndex value to the correct one so it APPEARS to be working great.... until you actually look at the resulting document.

While the code shows the correct selection being made when you view the saved document it shows NO selection as being made (none of the checkboxes in the radio button group are checked)

What am I missing?

I've googled all over but there seems to be very little help for AcroForm use in PDFSharp.


Top
 Profile  
Reply with quote  
PostPosted: Thu Mar 30, 2017 2:49 pm 
Offline

Joined: Wed Mar 29, 2017 4:22 pm
Posts: 12
Location: Virginia (USA)
Not only does it not seem to set them but it appears to break existing ones:

In order to try to compare what was different between a set and not set value I checked one of the boxes in the source pdf and saved it.
First problem is that the nuget version of PdfSharp wouldn't even open the newly saved version (apparently just checking a box and saving upgrades the version).
So I upgraded to the -pre version of PdfSharp (hey, maybe that would fix my radio button issue too right?) to see if that worked.
It does open the file and setting the text boxes still work but even if I comment out everything even referencing the radio button the resulting document loses the checked radio button from the source.

Inspecting the radio button in the new version shows it's Value as "/1" which doesn't make sense for a radio button as it has multiple kids and while the kid whose selected should be "/1" (the On value in this PDF) the value of the parent should be which kid is selected. In the non -Pre version this seemed to work corretly by having "/Choice1", "/Choice2", etc. in there depending on what SelectedIndex was set.

Again it's entirely possible I'm missing something but the behavior in the -Pre version seems more incorrect then the releave version with respect to radio buttons. (though the new version does allow for opening of higher version pdfs)

Any help here would be greatly appreciated.


Top
 Profile  
Reply with quote  
PostPosted: Wed Apr 05, 2017 7:02 pm 
Offline

Joined: Wed Mar 29, 2017 4:22 pm
Posts: 12
Location: Virginia (USA)
Ok I'm still trying to get this to work. Clearly the SelectedIndex and Value properties of the PdfRadioButtonField don't seem to work (meaning they don't visibly check the checkbox in the radio button group)

So I tried doing it myself manually as I understand it.
First, apparently PDFs don't have a standardized "On" value. So /Off is always off but on you have to figure out. I THINK I have that working.

To get it I do the following:
1. Get the PdfReference of one of the options from the RadioButtonField.Fields.Elements collection.
2. cast that reference to a PdfDictionary object
3. Get the AP Element of the Dictionary object
4. Get the N element of the AP Element
5. loop through the keys looking for the non-/Off value and save it. In my case it's "/1"

Once I have that I try to manually select the option by:
Taking the Dictionary object I initialized in step 2 above and doing Elements.SetName on both PdfAcroField.Keys.V and PdfAnnotation.Keys.AS with the value I got from step 5 above.
In theory this should select the element I grabbed in Step 1 above from the RadioButtonField so I can pick whichever one I wanted based on which member of the collection I grab.

This still doesn't work for me though so I'm clearly still missing something.

Again, any help here would be greatly appreciated.


Top
 Profile  
Reply with quote  
PostPosted: Thu Apr 06, 2017 7:08 pm 
Offline

Joined: Wed Mar 29, 2017 4:22 pm
Posts: 12
Location: Virginia (USA)
Ok I have a new discovery now.
I've been banging my head against the wall trying to get once radiobuttongroup to work but there is another one on the form.
On the other one if I set the Value = new pdfName("/Choice1" or "/Choice2") it works and selects one of the two checkboxes in that radio button group.
This however does not work in the first set. Not only that checking them in the file and saving it then loading it into pdfSharp causes it to lose it's value. This one has 5 choices but they seem to be named /Choice1, /Choice2, /Choice3, /Choice4, and /Choice4 again.
My GUESS is that the duplicate naming of /Choice4 is breaking pdfSharp. This appears to be ok as far a Acrobat reader is concerned though and the form works fine when you fill it out manually. (checking the fourth of fifth option doesn't check both and IS retained).
The problem is that IF my guess is even right we don't control the form. It's a government form that's given to us and we're just trying to automate filling in the form fields with entries from a database.
Can anyone confirm my guess is the issue (duplicate name fields) and offer any suggestions on how I can get around it and at least perserve the prechecked value. (I wouldn't even mind loading one of 5 different pdfs each with a different option pre-checked but right now pdfSharp loses even the prechecked value)


Top
 Profile  
Reply with quote  
PostPosted: Thu Apr 06, 2017 8:07 pm 
Offline

Joined: Wed Mar 29, 2017 4:22 pm
Posts: 12
Location: Virginia (USA)
Yet more info:
The RadioButtonField that DOES work does NOT have an /Opt Element.

The RedioButtonField that doesn't work and doesn't even retain a preset value DOES have an /Opt Element.
The issue in PDFSharp may be related to the bug reported here:

viewtopic.php?f=3&t=647

That bug was reported in 2009 but the only reply is from the bug submitter. I don't know if this bug was ever confirmed or fixed or what.


Top
 Profile  
Reply with quote  
PostPosted: Fri Apr 07, 2017 6:06 pm 
Offline

Joined: Wed Mar 29, 2017 4:22 pm
Posts: 12
Location: Virginia (USA)
Ok so my deadline is Monday and I'm running out of time. So now instead of trying to get it to work I've moved to trying to get it to not lose a selection that was saved in the file before it was opened.

Just to see where it was losing the preselected value I commented out everything. The program just opens the file (for modify) with the radio button group option already selected and then saves it. This keeps the value. I added back in lines until it lost the selection.

The selection seems to be lost when I add the "/NeedAppearances" key to the Elements collection of the AcroForm.
If I don't add this key the values I fill into the text boxes don't display unless the box has focus.

I'm not sure why adding a key to the form object would break a RadioButtonField but that's where I lose the preset value but I'm not sure where to go from here as not adding that key makes the text controls not work and adding it breaks the radiobutton.

Any help would be greatly appreciated.

Found this that may be related: https://forums.adobe.com/thread/1839021
Of course there's no answer to that either.


Top
 Profile  
Reply with quote  
PostPosted: Mon Apr 10, 2017 3:29 pm 
Offline

Joined: Wed Mar 29, 2017 4:22 pm
Posts: 12
Location: Virginia (USA)
If anyone is actually following this thread (or googles it later) we did get it to work but it's a hack and I'd still be interested in the correct way of making it work.

What's we're doing (and seems to work) is:
Remove the /Opt element from the Radio Button Field.
Add a /V element to the Radio Button Field.
Set the Value property of the Radio Button Field to the index of the Radio Button Field. ex: "/1" for the second option.

Why this works I have no idea... how the index works after you delete the option array seems unintuitive and I'm sure it's not "correct" but the correct radio button group is visibly checked in the resulting document when this is done.

Any thoughts on why this does work and/or the proper way to do it would be greatly appreciated.


Top
 Profile  
Reply with quote  
PostPosted: Tue Jan 30, 2018 11:23 am 
Offline

Joined: Tue Jan 30, 2018 11:15 am
Posts: 1
Hi

here is my workaround

Code:
rb = (PdfRadioButtonField)doc.AcroForm.Fields[0];
rb.Value = value;
PdfArray kids = (PdfArray)rb.Elements["/Kids"];
int i = 0;
foreach (var kid in kids)
{
    var kidValues = ((PdfReference)kid).Value as PdfDictionary;
    PdfRectangle rectangle = kidValues.Elements.GetRectangle(PdfAnnotation.Keys.Rect);
    if (i == index)
        kidValues.Elements.SetValue("/AS", value);
    else
        kidValues.Elements.SetValue("/AS", new PdfName("/Off"));
    i++;
}


PdfItem value - the value you have to set to be chacked
int index - the index of the option that has to be chacked


Top
 Profile  
Reply with quote  
PostPosted: Mon Feb 05, 2018 6:09 pm 
Offline

Joined: Mon Feb 05, 2018 4:04 pm
Posts: 1
Has there been any resolution to this. I am experiencing the same issue.


Top
 Profile  
Reply with quote  
PostPosted: Thu Feb 04, 2021 6:09 am 
Offline

Joined: Thu Feb 04, 2021 5:57 am
Posts: 2
Since this is high on the Google search results for PDFSharp and radio buttons, figured I'd share what seems to be working for me.

I created extension functions for the PdfRadioButtonField object that:
- Gets all option values and their indexes
- Sets the value for a radio field by index number
- Sets the value for a radio field by value

In the following examples, ErPdfRadioOption is:
Code:
 
    public class ErPdfRadioOption
    {
        public int Index { get; set; }
        public string Value { get; set; }
    }


Get all available options for a radio field

Code:
      public static List<ErPdfRadioOption> FindOptions(this PdfRadioButtonField source) {
            if (source == null) return null;
            List<ErPdfRadioOption> options = new List<ErPdfRadioOption>();

            PdfArray kids = source.Elements.GetArray("/Kids");

            int i = 0;
            foreach (var kid in kids) {
                PdfReference kidRef = (PdfReference)kid;
                PdfDictionary dict = (PdfDictionary)kidRef.Value;
                PdfDictionary dict2 = dict.Elements.GetDictionary("/AP");
                PdfDictionary dict3 = dict2.Elements.GetDictionary("/N");

                if (dict3.Elements.Keys.Count != 2)
                    throw new Exception("Option dictionary should only have two values");

                foreach (var key in dict3.Elements.Keys)
                    if (key != "/Off") { // "Off" is a reserved value that all non-selected radio options have
                        ErPdfRadioOption option = new ErPdfRadioOption() { Index = i, Value = key };
                        options.Add(option);
                    }
                i++;
            }

            return options;
        }



Set the option for a radio field by index
You'd think this is what the SelectedIndex property should be for... but apparently not.

Code:
        public static void SetOptionByIndex(this PdfRadioButtonField source,int index) {
            if (source == null) return;
            List<ErPdfRadioOption> options = source.FindOptions();
            ErPdfRadioOption selectedOption = options.Find(x => x.Index == index);
            if (selectedOption == null) return; //The specified index does not exist as an option for this radio field
           
            // https://forum.pdfsharp.net/viewtopic.php?f=2&t=3561
            PdfArray kids = (PdfArray)source.Elements["/Kids"];
            int j = 0;
            foreach (var kid in kids) {
                var kidValues = ((PdfReference)kid).Value as PdfDictionary;
                //PdfRectangle rectangle = kidValues.Elements.GetRectangle(PdfAnnotation.Keys.Rect);
                if (j == selectedOption.Index)
                    kidValues.Elements.SetValue("/AS", new PdfName(selectedOption.Value));
                else
                    kidValues.Elements.SetValue("/AS", new PdfName("/Off"));
                j++;
            }
        }

Note: This depends on the FindOptions() function above.


Set the option for a radio field by value

Code:
    public static void SetOptionByValue(this PdfRadioButtonField source, string value) {
            if (source == null || string.IsNullOrWhiteSpace(value)) return;
            if (!value.StartsWith("/", StringComparison.OrdinalIgnoreCase)) value = "/" + value; //All values start with a '/' character
            List<ErPdfRadioOption> options = source.FindOptions();
            ErPdfRadioOption selectedOption = options.Find(x => x.Value == value);
            if (selectedOption == null) return; //The specified index does not exist as an option for this radio field
            source.SetOptionByIndex(selectedOption.Index);
        }

Note: This depends on the FindOptions() and SetOptionByIndex() functions above.


Top
 Profile  
Reply with quote  
PostPosted: Thu Feb 04, 2021 6:19 am 
Offline

Joined: Thu Feb 04, 2021 5:57 am
Posts: 2
You'd use FindOptions() like this:

Code:
PdfDocument source;
PdfAcroField field = source.AcroForm.Fields[...]; //name or index of the field
PdfRadioButtonField radioField = field as PdfRadioButtonField;
return radioField.FindOptions();


Sample result (in JSON):

Code:
[
  {
    "Index": 0,
    "Value": "/Choice1"
  },
  {
    "Index": 1,
    "Value": "/Choice2"
  },
  {
    "Index": 2,
    "Value": "/Choice3"
  }
]



Use SetOptionByIndex(int index) like this

Code:
PdfDocument source;
PdfAcroField field = source.AcroForm.Fields[...]; //name or index of the field
PdfRadioButtonField radioField = field as PdfRadioButtonField;
radioField.SetOptionByIndex(index);


SetOptionByValue is basically the same as SetOptionByIndex, except accepts a string (actually, should probably just make it an overload... but meh).


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 11 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 51 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Privacy Policy, Data Protection Declaration, Impressum
Powered by phpBB® Forum Software © phpBB Group