TL;DR: Explore how the smart form-filling app uses AI technology to streamline form-filling in WPF PDF Viewer. Discover how this integration reduces manual input and errors by populating PDF form fields intelligently. Leveraging Syncfusion’s advanced components and Microsoft’s Semantic Kernel, this app offers a seamless and efficient user experience in document management.
Filling out forms is often tedious and error-prone when it comes to document management, particularly with large datasets. Smart fill addresses this issue by leveraging AI technologies to intelligently fill PDF form fields, thereby reducing manual input and enhancing accuracy.
In this blog, we’ll create a smart form-fill app using Syncfusion’s advanced WPF PDF Viewer to deliver a smooth and interactive document viewing experience. At the same time, it integrates with Microsoft’s Semantic Kernel to leverage AI capabilities. This integration facilitates the smart extraction and filling of user data, making the entire process more efficient and user-friendly.
How does it work?
Smart fill streamlines PDF form filling by integrating AI into a user-friendly WPF app. Users load PDFs into the app using our WPF PDF Viewer for seamless interaction. Then, the user’s data will be passed to the AI model to parse the details. By utilizing hint values for each form field within the PDFs, the app harnesses Microsoft’s Semantic Kernel to intelligently and accurately map the user data to the corresponding form fields. This automated process fills out the PDF forms quickly, reducing manual effort and minimizing errors, thereby enhancing both efficiency and user experience in document management.
Prerequisites
To build and run this app, you will need:
- Visual Studio with WPF workload.
- Syncfusion WPF PDF Viewer control.
- An API key for accessing Semantic Kernel.
Building a smart form-filling app using WPF PDF Viewer
Follow these steps to build an AI-powered smart PDF form-filling app using our WPF PDF Viewer control:
Step 1: Create a new WPF project
First, we need to create a new WPF project.
- Open Visual Studio and select the Create a new project option.
- From the available options, choose WPF App and proceed by clicking Next.
- In the project configuration, name your project as Smart_Fill and select an appropriate location for storing project files.
- Lastly, ensure the target framework is set to .NET 8.0 to align with the app’s required specifications.
Step 2: Configure project dependencies
With your project set up, navigate to the NuGet Package Manager in Visual Studio by choosing Tools ->NuGet Package Manager-> Manage NuGet Packages for Solution. Then, install the following packages:
- Syncfusion.PdfViewer.WPF
- Syncfusion.SfBusyIndicator.WPF
- Syncfusion.SfSkinManager.WPF
- Microsoft.SemanticKernel
Step 3: Design the user interface
Open the MainWindow.xaml file to begin designing the app’s user interface. Add a Grid layout and our WPF components like PdfViewerControl and SfBusyIndicator to facilitate PDF viewing and user interaction. Include essential controls such as buttons for executing actions and labels for displaying dynamic data. Ensure that the event handlers are linked to these controls to manage user interactions effectively.
Refer to the following code example.
<Window x:Class="Smart_Fill.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="7.5*" />
<ColumnDefinition Width="2.5*" />
</Grid.ColumnDefinitions>
<PdfViewer:PdfViewerControl x:Name="pdfViewer" Grid.Column="0" Loaded="pdfViewer_Loaded"/>
<Canvas x:Name="loadingCanvas" Background="White" Opacity="0.5" Visibility="Collapsed"/>
<Notification:SfBusyIndicator x:Name="loadingIndicator" Grid.Row="1" Visibility="Collapsed" IsBusy="True" AnimationType="DotCircle" ViewboxHeight="100" ViewboxWidth="200" Header="Loading..."/>
<Grid x:Name="smartFillGrid" Grid.Column="1">
<!-- Define UI for Smart Fill and buttons -->
<Button x:Name="smartFillButton" Content="Smart Fill" Click="SmartFillButton_Click" />
<!-- Additional UI Elements from where the user data will be copied-->
</Grid>
</Grid>
</Window>
Step 4: Configure Semantic AI Middleware
The purpose of the Semantic AI Middleware is to act as an intermediary layer between your app and the AI service. This middleware is responsible for:
- Initializing AI services,
- Composing AI prompts and
- Handling AI responses.
Here’s a simplified look at how this can be structured using the given SemanticKernelAI class.
internal class SemanticKernelAI
{
const string endpoint = "YOUR-AI-ENDPOINT";
const string deploymentName = "YOUR-DEPLOYMENT-NAME";
internal string key = string.Empty;
IChatCompletionService chatCompletionService;
Kernel kernel;
public SemanticKernelAI(string key)
{
this.key = key;
var builder = Kernel.CreateBuilder().AddAzureOpenAIChatCompletion(deploymentName, endpoint, key);
kernel = builder.Build();
chatCompletionService = kernel.GetRequiredService<IChatCompletionService>();
}
public async Task<string> GetAnswerFromGPT(string systemPrompt)
{
var history = new ChatHistory();
history.AddSystemMessage(systemPrompt);
OpenAIPromptExecutionSettings settings = new()
{
ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions
};
var result = await chatCompletionService.GetChatMessageContentAsync(history, executionSettings: settings, kernel: kernel);
return result.ToString();
}
}
Step 5: Implement the backend logic
Let’s incorporate the PDF handling code in the MainWindow.xaml.cs file using the WPF PDF Viewers’s API to enable document loading and display functionalities.
Constructor initialization
Use your API credentials to set up the Semantic Kernel to access OpenAI or another AI provider.
In the following code example, we will disable the open menu item in the WPF PDF Viewer control and add the AI assistance button.
public partial class MainWindow : Window
{
private SemanticKernelAI semanticKernelOpenAI;
public MainWindow()
{
InitializeComponent();
semanticKernelOpenAI = new SemanticKernelAI("YOUR-AI-KEY");
pdfViewer.Load("path/to/your/pdf.pdf");
}
private void pdfViewer_Loaded(object sender, RoutedEventArgs e)
{
// Get the text search stack panel from the toolbar of the PDF Viewer
DocumentToolbar toolbar = (DocumentToolbar)pdfViewer.Template.FindName("PART_Toolbar", pdfViewer);
// Collapse the open menu in the toolbar
CollapseOpenMenu(toolbar);
// Add the AI Assistance button to the toolbar
AddAIAssistanceButton(toolbar);
}
private void CollapseOpenMenu(DocumentToolbar toolbar)
{
//Get the instance of the file menu button using its template name.
ToggleButton FileButton = (ToggleButton)toolbar.Template.FindName("PART_FileToggleButton", toolbar);
//Get the instance of the file menu button context menu and the item collection.
ContextMenu FileContextMenu = FileButton.ContextMenu;
foreach (MenuItem FileMenuItem in FileContextMenu.Items)
{
//Get the instance of the open menu item using its template name and disable its visibility.
if (FileMenuItem.Name == "PART_OpenMenuItem")
FileMenuItem.Visibility = System.Windows.Visibility.Collapsed;
}
}
private void AddAIAssistanceButton(DocumentToolbar toolbar)
{
// Get the text search stack panel and annotation button from the toolbar
StackPanel textSeacrchStack = (StackPanel)toolbar.Template.FindName("PART_TextSearchStack", toolbar);
Button textSearchButton = (Button)toolbar.Template.FindName("PART_ButtonTextSearch", toolbar);
//Create a new toggle button for AI Assist
aIAssistButton = new Button();
TextBlock aIAssistText = new TextBlock();
aIAssistText.Text = "Smart Fill";
aIAssistText.FontSize = 14;
aIAssistButton.Content = aIAssistText;
aIAssistButton.Click += SmartFillButton_Click;
aIAssistButton.VerticalAlignment = VerticalAlignment.Center;
aIAssistButton.Margin = new Thickness(0, 0, 8, 0);
aIAssistButton.Padding = new Thickness(3);
// Set the style of the AI Assist button
aIAssistButton.SetResourceReference(Button.StyleProperty, "WPFPrimaryButtonStyle");
aIAssistText.SetResourceReference(Button.ForegroundProperty, "PrimaryForeground");
if(textSearchButton != null)
{
copyUserDataButton1.Style = textSearchButton.Style;
copyUserDataButton2.Style = textSearchButton.Style;
copyUserDataButton3.Style = textSearchButton.Style;
}
// Add the AI Assist button to the text search stack of the toolbar
if (textSeacrchStack.Children != null && textSeacrchStack.Children.Count > 0)
{
textSeacrchStack.Children.Insert(0, aIAssistButton);
}
else
{
textSeacrchStack.Children.Add(aIAssistButton);
}
// Apply the color to the buttons in the toolbar
ApplyColorToButtons(textSearchButton.Foreground, toolbar);
}
}
Providing hint for form field
To improve the accuracy of AI-assigned form filling, the app provides hints derived from the form field name using the HintValuesforFields method. This method traverses the form fields in the PDF, generating metadata, such as possible values for dropdowns or format instructions for date fields, guiding the AI in accurately filling the form.
private string HintValuesforFields()
{
string? hintData = null;
if(pdfViewer.LoadedDocument == null || pdfViewer.LoadedDocument.Form == null || pdfViewer.LoadedDocument.Form.Fields.Count <= 0)
{
return "";
}
// Iterate through each form field in the PDF viewer
foreach (PdfField field in pdfViewer.LoadedDocument.Form.Fields)
{
if (field is PdfLoadedComboBoxField)
{
PdfLoadedComboBoxField combo = field as PdfLoadedComboBoxField;
// Append ComboBox name and items to the hintData string
hintData += "\n" + combo.Name + " : Collection of Items are :";
foreach (PdfLoadedListItem item in combo.Values)
{
hintData += item.Text + ", ";
}
}
else if (field is PdfLoadedRadioButtonListField)
{
PdfLoadedRadioButtonListField? radio = field as PdfLoadedRadioButtonListField;
// Append RadioButton name and items to the hintData string
hintData += "\n" + radio.Name + " : Collection of Items are :";
foreach (PdfLoadedRadioButtonItem item in radio.Items)
{
hintData += item.Value + ", ";
}
}
else if (field is PdfLoadedListBoxField)
{
PdfLoadedListBoxField? list = field as PdfLoadedListBoxField;
// Append ListBox name and items to the hintData string
hintData += "\n" + list.Name + " : Collection of Items are :";
foreach (PdfLoadedListItem item in list.Values)
{
hintData += item.Text + ", ";
}
}
else if (field.Name.Contains("Date") || field.Name.Contains("dob") || field.Name.Contains("date"))
{
// Append instructions for date format to the hintData string
hintData += "\n" + field.Name + " : Write Date in MMM/dd/YYYY format";
}
// Append other form field names to the hintData string
}
// Return the hintData string if not null, otherwise return an empty string
if (hintData != null)
{
return hintData;
}
else
{
return "";
}
}
Copy the user data
Copying user data is a key feature that enables users to pass relevant information to the AI model. Buttons corresponding to user data sections are set up with click events. When a button is clicked, the corresponding text from a TextBlock is copied to the clipboard. This functionality is managed by dynamically displaying buttons when users hover over text sections.
private void CopyButton_Click(object sender, RoutedEventArgs e)
{
Button button = sender as Button;
if (button != null)
{
//Add a tooltip to the button
ToolTip toolTip = new ToolTip();
toolTip.Content = "Text Copied";
toolTip.PlacementTarget = button;
button.ToolTip = toolTip;
toolTip.IsOpen = true;
toolTipTimer.Start();
//Clear the clipboard and set the text to the clipboard
Clipboard.Clear();
if (button.Name.Contains("1"))
{
Clipboard.SetText(userDataText1.Text);
}
else if (button.Name.Contains("2"))
{
Clipboard.SetText(userDataText2.Text);
}
else if (button.Name.Contains("3"))
{
Clipboard.SetText(userDataText3.Text);
}
}
}
Parse and import the data to form field using WPF PDF Viewer API
The core functionality of parsing and filling the form data is executed through interaction with the Semantic Kernel AI. The GetDataFromAI method constructs a prompt that includes user data and field hints, then queries the AI model for a merged result with the desired output. The ImportDataToPdfViewer method subsequently reads the AI’s response and uses the PDF Viewer’s API to import this data into the form, completing the form automation cycle.
private async void SmartFillButton_Click(object sender, RoutedEventArgs e)
{
string result = await GetDataFromAI();
ImportDataToPdfViewer(result);
}
private async Task<string> GetDataFromAI()
{
string result = string.Empty;
// Get the selected user details from the combo box
string copiedDetails = Clipboard.GetText();
if (!string.IsNullOrEmpty(copiedDetails))
{
// Get the XFDF file content from the PDF Viewer
string loadedFileDetails = ExportFormDetails();
// Get the hint values for the form fields
string CustomValues = HintValuesforFields();
// Create a prompt message for the semantic kernel AI
string mergePrompt = $"Merge the input data into the XFDF file content. Hint text: {CustomValues}. " +
$"Ensure the input data matches suitable field names. " +
$"Here are the details: " +
$"input data: {copiedDetails}, " +
$"XFDF information: {loadedFileDetails}. " +
$"Provide the resultant XFDF directly. " +
$"Some conditions need to follow: " +
$"1. input data is not directly provided as the field name; you need to think and merge appropriately. " +
$"2. When comparing input data and field names, ignore case sensitivity. " +
$"3. First, determine the best match for the field name. If there isn’t an exact match, use the input data to find a close match. " +
$"remove ```
{% endraw %}
xml and remove
{% raw %}
``` if it is there in the code.";
// Get the answer from GPT using the semantic kernel AI
result = await semanticKernelOpenAI.GetAnswerFromGPT(mergePrompt);
}
return result;
}
private async void ImportDataToPdfViewer(string resultData)
{
var inputFileStream = new MemoryStream();
// Write the merged XFDF content to the MemoryStream
var writer = new StreamWriter(inputFileStream, leaveOpen: true);
await writer.WriteAsync(resultData);
await writer.FlushAsync();
inputFileStream.Position = 0;
// Import the data to the PDF Viewer from the MemoryStream
byte[] formData = new byte[inputFileStream.Length];
inputFileStream.Read(formData, 0, formData.Length);
pdfViewer.ImportFormData(formData, Syncfusion.Pdf.Parsing.DataFormat.XFdf);
}
Refer to the following image output.
GitHub reference
For more details, refer to the AI-powered smart PDF form-filling app using the WPF PDF Viewer GitHub demo.
Conclusion
Thanks for reading! By following these comprehensive instructions, you can successfully develop the smart form-filling app, combining AI-driven innovations with our robust Syncfusion components to streamline PDF form handling in a WPF environment.
Existing customers can download the latest version of Essential Studio® from the License and Downloads page. If you are not a customer, try our 30-day free trial to check out these new features.
If you have questions, contact us through our support forum, support portal, or feedback portal. We are always happy to assist you!
Top comments (0)