TL;DR: Learn how to integrate Azure OpenAI with the WinUI Scheduler for intelligent appointment booking. This guide walks you through setting up Azure OpenAI, retrieving AI responses, and leveraging Syncfusion’s WinUI Scheduler and AI AssistView controls to create a smart doctor appointment system with resource management and chatbot interaction. Enhance scheduling efficiency with AI-powered automation today!
A smarter scheduler powered by AI can transform appointment scheduling by making it faster, more efficient, and more user-friendly. By combining WinUI with cutting-edge Microsoft AI services, developers can create feature-rich apps that meet and exceed user expectations.
Start creating your smart scheduler today with the Microsoft AI services, Syncfusion WinUI Scheduler and AI AssistView controls to unlock the power of intelligent time management!
Let’s get started!
Integrating Azure OpenAI in a WinUI app
Getting started
- Begin by opening Visual Studio and creating a WinUI 3 desktop app.
- Ensure you have access to Azure OpenAI service and have set up a deployment in the Azure portal.
- Next, install the Microsoft.Extensions.AI.OpenAI, Azure.AI.OpenAI, and Azure.Identity NuGet packages from the NuGet Gallery.
Step 1: Connect to Azure OpenAI
In your app, replace the AZURE_OPENAI_ENDPOINT with your Azure OpenAI endpoint and modelId with your deployment name.
Then, refer to the following code example to connect Azure OpenAI using AzureOpenAIClient.
internal class AzureOpenAIBaseService
{
private const string endpoint = "AZURE_OPENAI_ENDPOINT";
private const string deploymentName = "DEPLOYMENT_NAME";
private const string key = "API_KEY";
private IChatClient? client;
private bool isAlreadyValidated;
internal AzureOpenAIBaseService()
{
ValidateCredential();
}
///<summary>
/// Validate Azure Credentials
///</summary
private async void ValidateCredential()
{
#region Azure OpenAI
// Use the below method for Azure Open AI
this.GetAzureOpenAIKernal();
#endregion
#endregion
if (isAlreadyValidated)
{
return;
}
try
{
if (client != null)
{
await client!.CompleteAsync("Hello, Test Check");
chatHistory = string.Empty;
IsCredentialValid = true;
isAlreadyValidated = true;
}
else
{
ShowAlertAsync();
}
}
catch (Exception)
{
return;
}
}
private void GetAzureOpenAIKernal()
{
try
{
var client = new AzureOpenAIClient(new Uri(endpoint), new AzureKeyCredential(key)).AsChatClient(modelId: deploymentName);
this.client = client;
}
catch (Exception)
{
}
}
}
Step 2: Get a response from Azure OpenAI
Now, send a prompt to Azure OpenAI and retrieve the completion result. Refer to the following code example.
internal class AzureOpenAIBaseService
{
private string? chatHistory;
internal async Task<string> GetAIResponse(string userPrompt)
{
if (IsCredentialValid && client != null)
{
chatHistory = string.Empty;
// Add the system message and user message to the options
chatHistory = chatHistory + "You are a predictive analytics assistant.";
chatHistory = chatHistory + userPrompt;
try
{
var response = await client.CompleteAsync(chatHistory);
return response.ToString();
}
catch
{
return string.Empty;
}
}
return string.Empty;
}
}
Next, declare the AzureOpenAIBaseService in the App.** Xaml.cs** file, which can be easily accessed in the app.
internal static AzureOpenAIBaseService? AzureBaseService { get; set; }
Then, validate the Azure OpenAI credential when the app loads, as shown in the following code example.
MainWindow.xaml.cs
public MainWindow()
{
this.InitializeComponent();
if(this.Content is Grid grid)
{
grid.Loaded += MainWindow_Loaded;
}
}
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
App.AzureBaseService = new AzureOpenAIBaseService();
}
Refer to the following image.
That’s it! The AzureOpenAIClient class now makes it easy to interact with OpenAI and retrieve the completion results using the prompt provided by the SfAIAssistView control.
Designing the WinUI Scheduler for doctors’ appointment management
The WinUI Scheduler control is used to schedule and manage appointments through an intuitive user interface, similar to the Windows calendar. It supports eight different views: day, week, workweek, month, timeline day, timeline week, timeline workweek, and timeline month. The control’s rich feature set includes:
- A built-in appointment editor to modify appointments.
- On-demand appointment loading.
- Localization to meet the needs of different regions and more.
It allows us to manage resources efficiently. Here, we’ll use it to easily add multiple doctors and group appointments into a single calendar, simplifying organization.
Step 1: Create a scheduler resource model
Create a resource model for a doctor, including fields like Name, Id, Background, Foreground, and ImageName to represent their information. Refer to the following code example.
ResourceViewModel.cs
public class ResourceViewModel
{
#region Properties
///<summary>
/// Gets or sets the name.
///</summary>
public string Name { get; set; }
///<summary>
/// Gets or sets the id.
///</summary>
public string? Id { get; set; }
///<summary>
/// Gets or sets the Background.
///</summary>
public Brush Background { get; set; }
///<summary>
/// Gets or sets the Foreground.
///</summary>
public Brush Foreground { get; set; }
///<summary>
/// Gets or sets the ImageName.
///</summary>
public string ImageName { get; set; }
#endregion
}
Step 2: Create resources for the WinUI Scheduler
Create resources (e.g., doctors) and assign them to the WinUI Scheduler. These resources will display the available doctors’ schedules on the calendar.
SchedulerViewModel.cs
public class SmartSchedulerViewModel
{
public ObservableCollection<object> Resources { get; set; }
public SmartSchedulerViewModel()
{
this.InitializeResourcesView();
}
/// <summary>
/// Method to initialize the resources.
/// </summary>
private void InitializeResourcesView()
{
for (int i = 0; i < 2; i++)
{
ResourceViewModel resourceViewModel = new ResourceViewModel();
if (i == 0)
{
resourceViewModel.Name = "Sophia";
resourceViewModel.ImageName = "/Assets/Scheduler/People_Circle" + i.ToString() + ".png";
resourceViewModel.Id = "1000";
resourceViewModel.Background = new SolidColorBrush(Color.FromArgb(0xFF, 0x36, 0xB3, 0x7B));
}
else
{
resourceViewModel.Name = "John";
resourceViewModel.ImageName = "/Assets/Scheduler/People_Circle" + i.ToString() + ".png";
resourceViewModel.Id = "1001";
resourceViewModel.Background = new SolidColorBrush(Color.FromArgb(255, 0x8B, 0x1F, 0xA9));
}
this.Resources?.Add(resourceViewModel);
}
}
}
Step 3: Add resources to the WinUI Scheduler
Now, bind the Resources property from the SchedulerViewModel class to the WinUI Scheduler’s ResourceCollection property. Then, map the custom properties of the ResourceViewModel class to the appropriate scheduler resource mapping properties of the ResourceMapping class. You can also customize the resource header template to improve visualization.
MainWindow.xaml
xmlns:scheduler="using:Syncfusion.UI.Xaml.Scheduler"
<Grid.DataContext>
<local:SmartSchedulerViewModel/>
</Grid.DataContext>
<scheduler:SfScheduler ViewType="Day"
ResourceCollection="{Binding Resources}"
ResourceGroupType="Resource">
<scheduler:SfScheduler.ResourceHeaderTemplate>
<DataTemplate>
<Grid Background="Transparent">
<StackPanel VerticalAlignment="Center"
Orientation="Vertical">
<Border CornerRadius="36"
Height="72"
Width="72"
BorderThickness="2"
BorderBrush="{Binding Data.Background}">
<Border CornerRadius="36"
Height="64"
Width="64"
BorderThickness="2"
BorderBrush="Transparent">
<Image HorizontalAlignment="Center"
VerticalAlignment="Center"
Width="55"
Height="55"
Source="{Binding Data.ImageName}" />
</Border>
</Border>
<TextBlock HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="15"
Text="{Binding Data.Name}" />
</StackPanel>
</Grid>
</DataTemplate>
</scheduler:SfScheduler.ResourceHeaderTemplate>
<scheduler:SfScheduler.ResourceMapping>
<scheduler:ResourceMapping Id="Id"
Name="Name"
Background="Background"
Foreground="Foreground" />
</scheduler:SfScheduler.ResourceMapping>
</scheduler:SfScheduler>
Refer to the following image.
Designing the WinUI AI Assistant chatbot
Let’s create an AI assistant chatbot in which users enter a prompt into the WinUI AI AssistView control to check doctors’ availability and interact with the chatbot for scheduling.
Refer to the following code example.
xmlns:assistView="using:Syncfusion.UI.Xaml.Chat"
<Grid.DataContext>
<local:SmartSchedulerViewModel/>
</Grid.DataContext>
<assistView:SfAIAssistView Height="400"
Margin="0,0,5,0"
VerticalAlignment="Top"
Background="{StaticResource SolidBackgroundFillColorTertiary}"
Suggestions="{Binding Suggestions}"
SuggestionSelected="OnChatSuggestionSelected"
CurrentUser="{Binding CurrentUser}"
Messages="{Binding Chats}">
<assistView:SfAIAssistView.BannerTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical"
Spacing="12">
<TextBlock Text="How can I assist with your health care needs?"
TextWrapping="Wrap"
Margin="20"
FontSize="20"
HorizontalAlignment="Center" />
<ListView x:Name="OptionstListView"
ItemsSource="{Binding AIAssistResources}"
SelectionMode="None"
Tapped="OnOptionstListViewTapped">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<Grid Height="120" Width="120">
<Border x:Name="ItemBorder"
BorderBrush="Gray"
BorderThickness="1"
Padding="4"
CornerRadius="10">
<Grid RowDefinitions="40,*">
<Image Grid.Row="0"
Height="30"
Width="30"
Margin="5"
Source="{Binding ImageName}"
HorizontalAlignment="Left" />
<Viewbox Height="30"
Grid.Row="0"
HorizontalAlignment="Right"
Width="30">
<Path Margin="4"
Data="M-1.97262e-07 4.51283L4.51283 9.02566L5.24581 8.29268L1.98425 5.03112L11.358 5.03112L11.358 3.99454L1.98425 3.99454L5.24581 0.732977L4.51283 1.97262e-07L-1.97262e-07 4.51283Z"
Fill="{ThemeResource TextBoxForegroundHeaderThemeBrush}">
<Path.RenderTransform>
<RotateTransform Angle="135"
CenterX="5"
CenterY="3" />
</Path.RenderTransform>
</Path>
</Viewbox>
<TextBlock Grid.Row="1"
Text="{Binding Name}"
TextWrapping="WrapWholeWords"
VerticalAlignment="Center"
HorizontalAlignment="Center" />
</Grid>
</Border>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackPanel>
</DataTemplate>
</assistView:SfAIAssistView.BannerTemplate>
</assistView:SfAIAssistView>
Refer to the following image.
Check the doctor’s availability using AI service
When the user inputs texts into the SfAIAssistView chatbot, the prompt is sent to the Azure OpenAI service, and the doctor’s availability times are listed in the SfAIAssistView smart component when the AI button is clicked.
Refer to the following code example to add Chats and Suggestions to the AI AssistView.
SchedulerViewModel.cs
private ObservableCollection<object> chats;
private ObservableCollection<string> suggestions;
public ObservableCollection<string> Suggestions
{
get
{
return this.suggestions;
}
set
{
this.suggestions = value;
this.RaisePropertyChanged(nameof(Suggestions));
}
}
public ObservableCollection<object> Chats
{
get
{
return this.chats;
}
set
{
this.chats = value;
this.RaisePropertyChanged(nameof(Chats));
}
}
public SmartSchedulerViewModel()
{
this.Chats = new ObservableCollection<object>();
this.Suggestions = new ObservableCollection<string>();
this.Chats.CollectionChanged += this.OnChatsCollectionChanged;
}
private void OnChatsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.NewItems?[0] is ITextMessage item)
{
string requestString = item.Text;
if (App.AzureBaseService != null && App.AzureBaseService.IsCredentialValid)
{
string pattern = @"\b\d{1,2}:\d{2} (AM|PM)\b";
bool isValidPattern = Regex.IsMatch(requestString.Trim(), pattern, RegexOptions.IgnoreCase);
string SuggestedTemplatedTime = @"\b\d{1,2}\s?(AM|PM)\b";
bool isSuggestedTemplatedTimePattern = Regex.IsMatch(requestString, SuggestedTemplatedTime);
if (requestString.Length == 8 && isValidPattern)
{
this.OnAssistViewRequest(requestString);
}
else if (item.Author.Name == currentUser.Name)
{
this.Suggestions.Clear();
this.GetResponseFromGPT(requestString);
}
}
}
}
Smartly schedule an appointment with a doctor based on their availability
When the user enters a booking time, the AI service checks the doctor’s availability, and the booking details are automatically converted into scheduler appointments without requiring direct interaction with the WinUI Scheduler.
Refer to the following code example to create appointments based on doctors’ availability.
SchedulerViewModel.cs
public ScheduleAppointmentCollection Appointments { get; set; } = new ScheduleAppointmentCollection();
private async void OnAssistViewRequest(string input)
{
string requeststring = input;
DateTime sophiaStartTime;
DateTime sophiaEndTime;
string sophiaSubject = string.Empty;
string sophiaLocation = string.Empty;
string sophiaResourceID = string.Empty;
DateTime johnStartTime;
DateTime johnEndTime;
string johnSubject = string.Empty;
string johnLocation = string.Empty;
string johnResourceID = string.Empty;
if (string.IsNullOrEmpty(requeststring))
{
return;
}
bool timeMatched = false;
for (int i = 0; i < this.SophiaAvailableTimeSlots?.Count; i++)
{
if (requeststring == this.SophiaAvailableTimeSlots[i].ToString())
{
timeMatched = true;
sophiaStartTime = this.SophiaStartTimeCollection![i];
sophiaEndTime = this.SophiaEndTimeCollection![i];
sophiaSubject = this.SophiaSubjectCollection![i];
sophiaLocation = this.SophiaLocationCollection![i];
sophiaResourceID = this.SophiaResourceIDCollection![i];
this.BookOnlineAppointments(sophiaStartTime, sophiaEndTime, sophiaSubject, sophiaLocation, sophiaResourceID);
await Task.Delay(1000);
this.Chats.Add(new TextMessage
{
Author = new Author { Name = "AI" },
DateTime = DateTime.Now,
Text = "Your appointment with Dr. Sophia has been booked. See you soon!"
});
}
}
for (int j = 0; j < this.JohnAvailableTimeSlots?.Count; j++)
{
if (requeststring == this.JohnAvailableTimeSlots[j].ToString())
{
timeMatched = true;
johnStartTime = this.JohnStartTimeCollection![j];
johnEndTime = this.JohnEndTimeCollection![j];
johnSubject = this.JohnSubjectCollection![j];
johnLocation = this.JohnLocationCollection![j];
johnResourceID = this.JohnResourceIDCollection![j];
this.BookOnlineAppointments(johnStartTime, johnEndTime, johnSubject, johnLocation, johnResourceID);
await Task.Delay(1000);
this.Chats.Add(new TextMessage
{
Author = new Author { Name = "AI" },
DateTime = DateTime.Now,
Text = "Your appointment with Dr. John has been booked. See you soon!"
});
}
}
if (!timeMatched)
{
await Task.Delay(1000);
this.Chats.Add(new TextMessage
{
Author = new Author { Name = "AI" },
DateTime = DateTime.Now,
Text = "This time is not available. Please enter an available time slot."
});
}
}
private void BookOnlineAppointments(DateTime startTime, DateTime endTime, string subject, string location, string resourceID)
{
this.DisplayDate = startTime;
this.Appointments.Add(new ScheduleAppointment()
{
StartTime = startTime,
EndTime = endTime,
Subject = subject,
Location = location,
ResourceIdCollection = new ObservableCollection<object>() { resourceID },
Foreground = new SolidColorBrush(Colors.White),
});
}
Refer to the following code example to bind appointments to the WinUI Scheduler.
<Grid.DataContext>
<local:SmartSchedulerViewModel/>
</Grid.DataContext>
<scheduler:SfScheduler ItemsSource="{Binding Appointments}"/>
Refer to the following image.
GitHub reference
For more details, refer to the AI-powered smart appointment booking app using the WinUI Scheduler GitHub demo.
Conclusion
Thank you for reading. In this blog, we’ve seen how to easily book appointments by integrating Microsoft Azure OpenAI- powered smart features with Syncfusion WinUI Scheduler and AI AssitView controls. Try out the steps in this blog and provide feedback in the comments section below.
Our customers can access the latest version of Essential Studio ® for WinUI from the License and Downloads page. If you are not a Syncfusion customer, you can download our free evaluation to explore all our controls.
For questions, you can contact us through our support forum, support portal, or feedback portal. We are always happy to assist you!
Top comments (0)