I'm using PDFSharp version 1.50.4740-beta5 from http://www.pdfsharp.net which I installed from NuGet.
I'm able to fill text form fields and checkbox form fields but I can't get radio buttons to work at all. I don't get an error. SelectedIndex is -1 before and after I set it to 1.
Several at articles on Stack Overflow have helped me to get this far. Has anyone successfully populated radio button form fields using this product? Here is a link to the sample PDF: http://www.myblackmer.com/bluebook/interactiveform_enabled.pdf
(Before you suggest iTextPdf, I've already evaluated it and Aspose.PDF and they are not practical)
//using PdfSharp.Pdf.IO;
//using PdfSharp.Pdf;
//using PdfSharp.Pdf.AcroForms;
string fileName = "x:\\interactiveform_enabled.pdf";
PdfSharp.Pdf.PdfDocument pdfDocument = PdfReader.Open(fileName);
//The populated fields are not visible by default
if (pdfDocument.AcroForm.Elements.ContainsKey("/NeedAppearances"))
{
pdfDocument.AcroForm.Elements["/NeedAppearances"] = new PdfBoolean(true);
}
else
{
pdfDocument.AcroForm.Elements.Add("/NeedAppearances", new PdfBoolean(true));
}
PdfRadioButtonField currentField = (PdfRadioButtonField)(pdfDocument.AcroForm.Fields["Sex"]);
currentField.ReadOnly = false;
currentField.SelectedIndex = 1;
pdfDocument.Flatten();
pdfDocument.Save("x:\\interactiveform_enabled_2.pdf");
The following worked for me:
Value
property with a PdfName
instance (not a PdfString
!)/
before the value nameExample, if you want to set the option "choice1" selected:
var radio = (PdfRadioButtonField)form.Fields["MyRadioButtonField"];
radio.Value = new PdfName("/choice1");
I found the solution at https://forum.pdfsharp.net/viewtopic.php?f=2&t=632
Since this is #1 in a Google search for "PDFSharp radio buttons", figured I'd share what seems to be working for me.
I created extension functions for the PdfRadioButtonField
object that:
In the following examples, ErPdfRadioOption
is:
public class ErPdfRadioOption
{
public int Index { get; set; }
public string Value { get; set; }
}
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;
}
Usage
PdfDocument source;
PdfAcroField field = source.AcroForm.Fields[...]; //name or index of the field
PdfRadioButtonField radioField = field as PdfRadioButtonField;
return radioField.FindOptions();
Result (JSON)
[
{
"Index": 0,
"Value": "/Choice1"
},
{
"Index": 1,
"Value": "/Choice2"
},
{
"Index": 2,
"Value": "/Choice3"
}
]
You'd think this is what the SelectedIndex
property should be for... but apparently not.
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.
Usage
PdfDocument source;
PdfAcroField field = source.AcroForm.Fields[...]; //name or index of the field
PdfRadioButtonField radioField = field as PdfRadioButtonField;
radioField.SetOptionByIndex(index);
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.
Based on this post in the PDFsharp forum: https://forum.pdfsharp.net/viewtopic.php?f=2&t=3561#p11386
Using PDFsharp version 1.50.5147
Based on Chris's answer, the salient point is that you have to set the value for all options to \\Off while setting the option's value you want to the \\Choice. To that end, you can have a simple function like:
//sets a radio button option by setting the index and value and turning the others off
static void setRadioOption (PdfRadioButtonField field, int option, string optvalue)
{
PdfArray kids = (PdfArray)field.Elements["/Kids"];
int j = 0;
foreach (var kid in kids)
{
var kidValues = ((PdfReference)kid).Value as PdfDictionary;
if (j == option)
kidValues.Elements.SetValue("/AS", new PdfName(optvalue));
else
kidValues.Elements.SetValue("/AS", new PdfName("/Off"));
j++;
}
}
Is it me you're looking for?
private static void SetPdfRadiobutton(PdfDocument document, string fieldname, string newvalue, int item)
{
PdfRadioButtonField field = (PdfRadioButtonField)document.AcroForm.Fields[fieldname];
PdfArray items = (PdfArray)field.Elements["/Kids"];
for (int i = 0; i < items.Elements.Count; i++)
{
PdfDictionary keys = ((PdfReference)items.Elements[i]).Value as PdfDictionary;
keys.Elements.SetValue("/AS", i == item ? new PdfName(newvalue) : new PdfName("/Off"));
}
field.ReadOnly = true;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.