Skip to content

Commit 000161c

Browse files
Merge pull request #3576 from syncfusion-content/DataFormSmartAISample
UG Document for Smart AI Data Entry Sample in MAUI DataForm.
2 parents c54115a + cd75773 commit 000161c

File tree

3 files changed

+396
-0
lines changed

3 files changed

+396
-0
lines changed
Lines changed: 395 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,395 @@
1+
---
2+
layout: post
3+
title: AI-powered Smart .NET MAUI Dataform for Data Entry | Syncfusion®
4+
description: Learn here all about how to build an AI powered smart data entry in .NET MAUI SfDataForm by integrating Azure OpenAI.
5+
platform: maui
6+
control: SfDataForm
7+
documentation: ug
8+
---
9+
10+
# AI-powered Smart .NET MAUI Dataform for Data Entry
11+
12+
This guide explains how to implement AI-powered smart data forms in a .NET MAUI application using Syncfusion® DataForm ([SfDataForm](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.DataForm.SfDataForm.html)) and AIAssistView ([SfAIAssistView](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.AIAssistView.SfAIAssistView.html)) controls. These forms automatically generate fields, validate input, and guide users interactively using AI logic from Azure OpenAI Services.
13+
14+
## Integrating Azure OpenAI with the .NET MAUI app
15+
16+
### Step 1: Set Up the .NET MAUI Project
17+
18+
Create a [.NET MAUI app](https://learn.microsoft.com/en-us/dotnet/maui/get-started/first-app?view=net-maui-9.0&viewFallbackFrom=net-maui-7.0&tabs=vswin&pivots=devices-android) in [Visual Studio](https://visualstudio.microsoft.com/) and install the following NuGet packages: `Syncfusion.Maui.DataForm`, `Syncfusion.Maui.AIAssistView`, [`Azure.AI.OpenAI`](https://www.nuget.org/packages/Azure.AI.OpenAI/1.0.0-beta.12), [`Microsoft.Extensions.AI.OpenAI`](https://www.nuget.org/packages/Microsoft.Extensions.AI.OpenAI/9.8.0-preview.1.25412.6) and [`Azure.Identity`](https://www.nuget.org/packages/Azure.Identity) from [NuGet Gallery](https://www.nuget.org/)
19+
20+
### Step 2: Set up Azure OpenAI
21+
22+
To enable AI functionality in your .NET MAUI Scheduler, first ensure that you have access to [Azure OpenAI](https://azure.microsoft.com/en-in/products/ai-services/openai-service). In the Azure portal, create an Azure OpenAI resource and deploy a model such as GPT-35. Assign a deployment name (for example, GPT35Turbo) that you’ll reference in your application code. Finally, copy the API key and endpoint URL from the resource settings, as these are required for authentication and communication with the OpenAI service.
23+
24+
### Step 3: Connect to the Azure OpenAI
25+
26+
To connect your .NET MAUI app to Azure OpenAI, create a service class that handles communication with the AI model.
27+
28+
```
29+
/// <summary>
30+
/// Represents Class to interact with Azure AI.
31+
/// </summary>
32+
internal class DataFormAIService : AzureBaseService
33+
{
34+
35+
}
36+
```
37+
In this service, define a method called `GetAnswerFromGPT`. This method takes a user prompt from the SfAIAssistView control as input, sends it to the deployed model (e.g., GPT35Turbo), and returns the AI-generated response.
38+
39+
```
40+
/// <summary>
41+
/// Represents Class to interact with Azure AI.
42+
/// </summary>
43+
public class AzureAIServices : AzureBaseService
44+
{
45+
/// <summary>
46+
/// Initializes a new instance of the <see cref="AzureAIServices"/> class.
47+
/// </summary>
48+
public AzureAIServices()
49+
{
50+
51+
}
52+
53+
/// <summary>
54+
/// Retrieves an answer from the deployment name model using the provided user prompt.
55+
/// </summary>
56+
/// <param name="userPrompt">The user prompt.</param>
57+
/// <returns>The AI response.</returns>
58+
internal async Task<string> GetAnswerFromGPT(string userPrompt)
59+
{
60+
ChatHistory = string.Empty;
61+
if (IsCredentialValid && Client != null && ChatHistory != null)
62+
{
63+
// Add the user's prompt as a user message to the conversation.
64+
ChatHistory = ChatHistory + "You are a predictive analytics assistant.";
65+
// Add the user's prompt as a user message to the conversation.
66+
ChatHistory = ChatHistory + userPrompt;
67+
try
68+
{
69+
//// Send the chat completion request to the OpenAI API and await the response.
70+
var response = await Client.CompleteAsync(ChatHistory);
71+
return response.ToString();
72+
}
73+
catch
74+
{
75+
// If an exception occurs (e.g., network issues, API errors), return an empty string.
76+
return "";
77+
}
78+
}
79+
80+
return "";
81+
}
82+
}
83+
}
84+
```
85+
86+
Within the base service class (AzureBaseService), initialize the OpenAIClient with your Azure endpoint, deployment name, and API key.
87+
88+
```
89+
public abstract class AzureBaseService
90+
{
91+
#region Fields
92+
/// <summary>
93+
/// The EndPoint
94+
/// </summary>
95+
internal const string Endpoint = "YOUR_END_POINT_NAME";
96+
97+
/// <summary>
98+
/// The Deployment name
99+
/// </summary>
100+
internal const string DeploymentName = "DEPLOYMENT_NAME";
101+
102+
/// <summary>
103+
/// The Image Deployment name
104+
/// </summary>
105+
internal const string ImageDeploymentName = "IMAGE_DEPOLYMENT_NAME";
106+
107+
/// <summary>
108+
/// The API key
109+
/// </summary>
110+
internal const string Key = "API_KEY";
111+
112+
/// <summary>
113+
/// The already credential validated field
114+
/// </summary>
115+
private static bool isAlreadyValidated = false;
116+
117+
/// <summary>
118+
/// Indicating whether an credentials are valid or not
119+
/// </summary>
120+
private static bool _isCredentialValid;
121+
122+
#endregion
123+
124+
public AzureBaseService()
125+
{
126+
ValidateCredential();
127+
}
128+
129+
internal IChatClient? Client { get; set; }
130+
131+
/// <summary>
132+
/// To get the Azure open ai method
133+
/// </summary>
134+
private void GetAzureOpenAI()
135+
{
136+
try
137+
{
138+
var client = new AzureOpenAIClient(new Uri(Endpoint), new AzureKeyCredential(Key)).AsChatClient(modelId: DeploymentName);
139+
this.Client = client;
140+
}
141+
catch (Exception)
142+
{
143+
}
144+
}
145+
}
146+
```
147+
148+
## Integrating AI-powered smart DataForm Generation in .NET MAUI DataForm
149+
150+
### Step 1: Designing the User Interface
151+
152+
#### Editor and Button - Capturing User Prompts
153+
154+
Use an Editor to collect natural language prompts and a Button to send the prompt to Azure OpenAI. The Editor allows users to describe the form they want, while the Button triggers the logic to process the prompt and generate the form.
155+
156+
```
157+
<VerticalStackLayout Margin="20" VerticalOptions="Center" HorizontalOptions="Center">
158+
<Label x:Name="describeLabel"
159+
Text="Create AI-Powered Smart Forms in .NET MAUI for Efficient Productivity."
160+
LineBreakMode="WordWrap" FontSize="Small" FontAttributes="Bold" />
161+
<Grid ColumnDefinitions="0.7*,0.3*" Margin="10" ColumnSpacing="5">
162+
163+
<Editor AutoSize="TextChanges" x:Name="entry"
164+
PlaceholderColor="Gray"
165+
VerticalOptions="Center"
166+
HorizontalOptions="Fill"
167+
Placeholder="Create your own data form" />
168+
<Button x:Name="createButton"
169+
Grid.Column="1" CornerRadius="10"
170+
HeightRequest="35" Text="&#xe784;"
171+
FontSize="Small"
172+
FontFamily="MauiMaterialAssets"
173+
VerticalOptions="Center" HorizontalOptions="Start" />
174+
</Grid>
175+
</VerticalStackLayout>
176+
```
177+
178+
#### Busy Indicator - Showing Processing Status
179+
180+
The SfBusyIndicator provides visual feedback while the AI processes the prompt. It is shown during form generation and hidden once the form is ready.
181+
182+
```
183+
xmlns:core="clr-namespace:Syncfusion.Maui.Core;assembly=Syncfusion.Maui.Core"
184+
185+
<core:SfBusyIndicator IsVisible="False"
186+
x:Name="busyIndicator"
187+
IsRunning="False"
188+
AnimationType="Cupertino" />
189+
```
190+
191+
#### DataForm - Displaying the Generated Form
192+
193+
The SfDataForm renders the generated form dynamically based on the AI response.
194+
195+
```
196+
xmlns:dataform="clr-namespace:Syncfusion.Maui.DataForm;assembly=Syncfusion.Maui.DataForm"
197+
198+
<dataform:SfDataForm x:Name="dataForm"
199+
Grid.RowSpan="1"
200+
Grid.Row="1" AutoGenerateItems="False"
201+
ValidationMode="PropertyChanged"
202+
LayoutType="TextInputLayout"
203+
HorizontalOptions="Center">
204+
<dataform:SfDataForm.TextInputLayoutSettings>
205+
<dataform:TextInputLayoutSettings ShowHelperText="True"/>
206+
</dataform:SfDataForm.TextInputLayoutSettings>
207+
</dataform:SfDataForm>
208+
```
209+
210+
#### AI AssistView - Providing Suggestions
211+
212+
The SfAIAssistView offers contextual help, such as real-time suggestions or chatbot-style assistance.
213+
214+
```
215+
<aiassistview:SfAIAssistView x:Name="aiAssistView"
216+
Grid.Row="1" HorizontalOptions="Fill"
217+
ShowHeader="False"
218+
AssistItems="{Binding Messages}">
219+
<aiassistview:SfAIAssistView.Behaviors>
220+
<local:DataFormAssistViewBehavior x:Name="dataFormAssistViewModel" AIActionButton="{x:Reference aiActionButton}" RefreshButton="{x:Reference refreshButton}" CloseButton="{x:Reference close}"
221+
DataFormNameLabel="{x:Reference dataFormNameLabel}" BusyIndicator="{x:Reference busyIndicator}" DataForm="{x:Reference dataForm}" DataFormGeneratorModel="{x:Reference dataFormGeneratorModel}" Entry="{x:Reference entry}" CreateButton="{x:Reference createButton}"/>
222+
</aiassistview:SfAIAssistView.Behaviors>
223+
</aiassistview:SfAIAssistView>
224+
```
225+
226+
### Step 2: Create and Edit Data Form Items using Azure OpenAI
227+
228+
#### Creating Data Form Items
229+
230+
We first create a button click event that triggers the AI-powered form item generation process.
231+
232+
```
233+
private async void OnCreateButtonClicked(object? sender, EventArgs e)
234+
{
235+
UpdateBusyIndicator(true);
236+
237+
if (AzureBaseService.IsCredentialValid && Entry?.Text is string text && !string.IsNullOrEmpty(text))
238+
{
239+
GetDataFormFromAI(text);
240+
}
241+
else if (!string.IsNullOrEmpty(DataFormGeneratorModel?.FormTitle))
242+
{
243+
await CreateOfflineDataForm(DataFormGeneratorModel.FormTitle);
244+
DataFormGeneratorModel.ShowInputView = false;
245+
DataFormGeneratorModel.ShowDataForm = true;
246+
}
247+
248+
}
249+
```
250+
251+
#### Generate Items from User Prompts
252+
253+
The following method sends the user’s prompt to Azure OpenAI and processes the response to generate actions such as New Form, Change Title, Add, Remove, or Replace.
254+
255+
```
256+
internal async void GetDataFormFromAI(string userPrompt)
257+
{
258+
string prompt = $"Given the user's input: {userPrompt}, determine the most appropriate single action to take. " +
259+
$"The options are 'Add', 'Add Values','PlaceholderText' ,'Remove', 'Replace', 'Insert', 'New Form', 'Change Title', or 'No Change'" +
260+
" Without additional formatting and special characters like backticks, newlines, or extra spaces.";
261+
262+
var response = await this.semanticKernelService.GetAnswerFromGPT(prompt);
263+
264+
if (string.IsNullOrEmpty(response))
265+
{
266+
AssistItem subjectMessage = new AssistItem() { Text = "Please try again...", ShowAssistItemFooter = false };
267+
this.DataFormGeneratorModel?.Messages.Add(subjectMessage);
268+
UpdateCreateVisibility();
269+
UpdateBusyIndicator(false);
270+
}
271+
else
272+
{
273+
if (response == string.Empty)
274+
{
275+
UpdateBusyIndicator(false);
276+
if (Application.Current != null)
277+
{
278+
var mainWindow = Application.Current.Windows.FirstOrDefault();
279+
if (mainWindow != null && mainWindow.Page != null)
280+
{
281+
await mainWindow.Page.DisplayAlert("", "Please enter valid inputs.", "OK");
282+
}
283+
}
284+
}
285+
else if (response == "New Form")
286+
{
287+
if (this.DataFormGeneratorModel != null)
288+
this.DataFormGeneratorModel.ShowOfflineLabel = false;
289+
this.GenerateAIDataForm(userPrompt);
290+
}
291+
else if (response == "Change Title")
292+
{
293+
string dataFormNamePrompt = $"Change the title for data form based on user prompt: {userPrompt}. Provide only the title, with no additional explanation";
294+
string getDataFormName = await this.semanticKernelService.GetAnswerFromGPT(dataFormNamePrompt);
295+
this.DataFormNameLabel!.Text = getDataFormName;
296+
AssistItem subjectMessage = new AssistItem() { Text = "The Data Form title changed successfully...", ShowAssistItemFooter = false };
297+
this.DataFormGeneratorModel?.Messages.Add(subjectMessage);
298+
}
299+
else
300+
{
301+
this.EditDataForm(userPrompt, response);
302+
}
303+
}
304+
}
305+
```
306+
307+
```
308+
private async void GenerateAIDataForm(string userPrompt)
309+
{
310+
string dataFormNamePrompt = $"Generate a title for a data form based on the following string: {userPrompt}. The title should clearly reflect the purpose of the data form in general term. Provide only the title, with no additional explanation";
311+
string getDataFormName = await this.semanticKernelService.GetAnswerFromGPT(dataFormNamePrompt);
312+
this.DataFormNameLabel!.Text = getDataFormName;
313+
314+
string prompt = $"Generate a data form based on the user prompt: {userPrompt}.";
315+
string condition = "Property names must be in PascalCase. " +
316+
"Must be property names and its value " +
317+
"Without additional formatting characters like backticks, newlines, or extra spaces. " +
318+
"and map each property to the most appropriate DataForm available item type includes: DataFormTextItem , DataFormMultiLineTextItem, DataFormPasswordItem, DataFormNumericItem, DataFormMaskedTextItem, DataFormDateItem, DataFormTimeItem, DataFormCheckBoxItem, DataFormSwitchItem, DataFormPickerItem, DataFormComboBoxItem, DataFormAutoCompleteItem, DataFormRadioGroupItem, DataFormSegmentItem" +
319+
"The result must be in JSON format" +
320+
"Without additional formatting characters like backticks, newlines, or extra spaces.";
321+
322+
var typeResponse = await this.semanticKernelService.GetAnswerFromGPT(prompt + condition);
323+
324+
var dataFormTypes = JsonConvert.DeserializeObject<Dictionary<string, object>>(typeResponse);
325+
326+
if (this.DataForm != null && dataFormTypes != null)
327+
{
328+
var items = new ObservableCollection<DataFormViewItem>();
329+
foreach (var data in dataFormTypes)
330+
{
331+
DataFormItem? dataFormItem = GenerateDataFormItems(data.Value.ToString(), data.Key);
332+
if (dataFormItem != null)
333+
items.Add(dataFormItem);
334+
}
335+
336+
this.DataForm.Items = items;
337+
}
338+
339+
AssistItem subjectMessage = new AssistItem() { Text = "As per your comment data form created successfully...", ShowAssistItemFooter = false };
340+
this.DataFormGeneratorModel?.Messages.Add(subjectMessage);
341+
342+
UpdateCreateVisibility();
343+
UpdateBusyIndicator(false);
344+
}
345+
```
346+
347+
#### Generating a New Data Form
348+
349+
When the user request is identified as "New Form", a complete form can be created dynamically.
350+
351+
#### Editing Data Form Items
352+
353+
Azure OpenAI also allows editing an existing form. The following operations are supported:
354+
355+
(a) Add a New Item
356+
357+
* Generates a new property and maps it to the best fitting DataForm item type.
358+
359+
(b) Remove an Item
360+
361+
* Finds and removes an existing property from the DataForm.
362+
363+
(c) Replace an Item
364+
365+
* Replaces one form field with another.
366+
367+
(d) Add Values to a Field
368+
369+
* Populates additional values into picker or combo-box items.
370+
371+
#### Handling Requests via AIAssistView
372+
373+
Finally, the `Request` event in AIAssistView listens to user inputs and invokes the data form generation or edit methods.
374+
375+
With these implementations, the DataForm becomes AI-powered, enabling users to create and modify form structures dynamically via Azure OpenAI.
376+
377+
```
378+
private async void OnAssistViewRequest(object? sender, RequestEventArgs e)
379+
{
380+
string requestText = e.RequestItem.Text;
381+
if (AzureBaseService.IsCredentialValid && this.DataFormGeneratorModel != null)
382+
{
383+
this.DataFormGeneratorModel.ShowOfflineLabel = false;
384+
this.GetDataFormFromAI(requestText);
385+
return;
386+
}
387+
388+
await CreateOfflineDataForm(requestText);
389+
}
390+
391+
```
392+
393+
![AI powered Smart .NET MAUI Dataform](images/smart-ai-samples/Create-Data-Form-with-AI-technology-in-.NET-MAUI.gif)
394+
395+
You can download the complete sample from this [link](https://github.com/syncfusion/maui-demos/tree/master/MAUI/SmartComponents/SampleBrowser.Maui.SmartComponents/Samples/SmartComponents/SmartDataForm).
453 KB
Loading

0 commit comments

Comments
 (0)