Skip to main content
All docs
V24.2

AI Chat Control

  • 6 minutes to read

Note

The DevExpress AI Chat Control (AIChatControl) can only be used in Windows Forms applications that target the .NET 8+ framework.

The AI Chat Control (AIChatControl) allows you to incorporate an interactive, Copilot-inspired chat-based UI within your WinForms application. This control leverages BlazorWebView to reuse the DevExpress Blazor AI Chat component (DxAIChat). To use the WinForms AI Chat Control you must have one of the following active subscriptions: Universal, DXperience, ASP.NET & Blazor.

WinForms AI Chat Control, DevExpress

Getting Started

1. Install DevExpress NuGet Packages

  1. DevExpress.AIIntegration.WinForms.Chat
  2. DevExpress.Win.Design (enables design-time features for DevExpress UI controls)

2. Change Project SDK

Update the project SDK to Microsoft.NET.Sdk.Razor:

<Project Sdk="Microsoft.NET.Sdk.Razor">

3. Register AI Client

The following code snippet registers the Azure OpenAI client:

using Microsoft.Extensions.AI;
using DevExpress.AIIntegration;

internal static class Program {
    [STAThread]
    static void Main() {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        IChatClient asChatClient = new Azure.AI.OpenAI.AzureOpenAIClient(new Uri(AzureOpenAIEndpoint),
            new System.ClientModel.ApiKeyCredential(AzureOpenAIKey))
            .AsChatClient("GPT4o");
        AIExtensionsContainerDesktop.Default.RegisterChatClient(asChatClient);
        Application.Run(new Form1());
    }
    static string AzureOpenAIEndpoint { get { return Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT"); } }
    static string AzureOpenAIKey { get { return Environment.GetEnvironmentVariable("AZURE_OPENAI_APIKEY"); } }
}

Tip

Read the following help topic for additional information: How to Register an AI Client.

4. Create AI Chat Control

Drop the AIChatControl from the toolbox onto a Form.

Note

The AI Chat Control does not support design-time rendering.

The following code snippet creates the AIChatControl with default settings:

using DevExpress.AIIntegration.WinForms.Chat;

public partial class Chat : XtraForm {
    public Chat() {
        InitializeComponent();

        AIChatControl chat = new AIChatControl(){
            Name = "aiChatControl1",
            Dock = DockStyle.Fill
        };
        this.Controls.Add(chat);
    }
}

Streaming

The AI Chat Control can display responses from the AI assistant as they are generated in a natural, conversational flow (rather than waiting for the entire message to complete before showing it to the user). Enable the UseStreaming setting to activate streaming:

aiChatControl1.UseStreaming = DevExpress.Utils.DefaultBoolean.True;

Play the following animation to see the result:

Streaming - WinForms AI Chat Control, DevExpress

Markdown Message Rendering

  • Set the ContentFormat property to Markdown to receive responses as Markdown.
  • Handle the MarkdownConvert event to convert markdown text into HTML and make responses more readable, structured, and visually appealing.

The following example enables Markdown message rendering. The example uses the Markdig Markdown processing library to convert Markdown text into HTML.

public Chat() {
    InitializeComponent();
    aiChatControl1.ContentFormat = DevExpress.AIIntegration.Blazor.Chat.ResponseContentFormat.Markdown
    aiChatControl1.MarkdownConvert += AiChatControl1_MarkdownConvert
}

void AiChatControl1_MarkdownConvert(object sender, DevExpress.AIIntegration.Blazor.Chat.WebView.AIChatControlMarkdownConvertEventArgs e) {
    e.HtmlText = (MarkupString)Markdown.ToHtml(e.MarkdownText);
}

The following screenshot shows the result:

Markdown Message Rendering - WinForms AI Chat Control, DevExpress

Handle Chat Messages

To manually process messages sent to an AI service, handle the MessageSent event. For example, you can manually call the AI client or service of choice and return its responses to the chat. The following example adds responses to user questions:

using DevExpress.AIIntegration.Blazor.Chat.WebView;
using Microsoft.Extensions.AI;

public Chat() {
    InitializeComponent();
    aiChatControl1.MessageSent += AiChatControl1_MessageSent;
}

async void AiChatControl1_MessageSent(object sender, AIChatControlMessageSentEventArgs e) {
    await e.SendMessage($"Processed: {e.Content}", ChatRole.Assistant);
}

Save and Load Chat History

Use the following methods to manage chat history:

  • SaveMessages – Returns an IEnumerable<ChatMessage> collection of messages.
  • LoadMessages – Loads messages from the specified IEnumerable<ChatMessage> collection to the AI Chat Control and refreshes the control.

The following example saves/loads chat history when the user clicks the Save/Load button:

public partial class Chat : XtraForm {
    List<BlazorChatMessage> chatHistory;
    public Chat() {
        InitializeComponent();
        buttonSave.Click += ButtonSave_Click;
        buttonLoad.Click += ButtonLoad_Click;
    }

    void ButtonSave_Click(object sender, EventArgs e) {
        chatHistory = (List<BlazorChatMessage>)aiChatControl1.SaveMessages();
    }

    void ButtonLoad_Click(object sender, EventArgs e) {
        if(chatHistory != null)
            aiChatControl1.LoadMessages(chatHistory);
    }
}

Create an Assistant That Chats Using Your Own Data

When integrating the OpenAI Assistant, you can configure it to retain and reference a specific context (for example, a text file or a PDF document). By providing a supplementary document as a context source, the assistant is primed with background information. OpenAI automatically parses the document and searches through it to retrieve relevant content to better respond to user queries.

  1. Install the DevExpress.AIIntegration.OpenAI NuGet package. Add the highlighted code to the Program.cs file to register the OpenAI Assistant service:

    static void Main() {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
    
        IChatClient asChatClient = new Azure.AI.OpenAI.AzureOpenAIClient(new Uri(AzureOpenAIEndpoint),
        new System.ClientModel.ApiKeyCredential(AzureOpenAIKey))
        .AsChatClient("GPT4o");
        AIExtensionsContainerDesktop.Default.RegisterChatClient(asChatClient);
    
        AIExtensionsContainerDesktop.Default.RegisterOpenAIAssistants(new AzureOpenAIClient(new Uri(azureOpenAIEndpoint),
                new System.ClientModel.ApiKeyCredential(azureOpenAIKey)), "Gpt4o");
    
        Application.Run(new Chat());
    }
    
  2. Handle the Initialized event with an async handler. Call the e.SetupAssistantAsync method to supply a file and a prompt to the Open AI Assistant:

    using System.IO;
    using DevExpress.AIIntegration.OpenAI.Services;
    using DevExpress.AIIntegration.Blazor.Chat.WebView;
    
    public partial class Chat : XtraForm {
        FileStream dataStream;
        public Chat() {
            InitializeComponent();
            dataStream = File.OpenRead(@"RestaurantMenu.pdf");
            /*
             * In this example, aiChatControl1 was created and configured at design time.
             */
            aiChatControl1.Initialized += AiChatControl1_Initialized;
        }
        async void AiChatControl1_Initialized(object sender, AIChatControlInitializedEventArgs e) {
            await e.SetupAssistantAsync(new OpenAIAssistantOptions("RestaurantMenu.pdf", dataStream, "You are an Analyst Assistant specializing in PDF file analysis. Your role is to assist users by providing accurate answers to their questions about data contained in these files."));    
        }
    }
    

The following screenshot shows the result:

AI Assistant

Customize Empty Text

Use the EmptyStateText property to specify the message displayed when a chat has yet to start:

aiChatControl1.EmptyStateText = "AI Assistant is ready to answer your questions.";

The following screenshot shows the result:

Custom Empty Text - WinForms AI Chat Control, DevExpress

See Also