windowsforms-405151-ai-powered-extensions.md
.NET 8 SDK / .NET Framework v4.7.2
OpenAI
Azure OpenAI
Semantic Kernel
Ollama (self-hosted models)
Foundry Local (on-device AI models)
ONNX Runtime (local ONNX models)
DevExpress.AIIntegration assemblies reference the following versions of Microsoft.Extensions.AI.* NuGet packages:
| Package Name | v25.2 |
|---|---|
Microsoft.Extensions.AI | 9.7.1 |
Microsoft.Extensions.AI.OpenAI | 9.7.1-preview.1.25365.4 |
See the following breaking change advisory for more information: DevExpress.AIIntegration references stable versions of Microsoft AI packages.
Install the following DevExpress NuGet Packages:
DevExpress.AIIntegration.WinFormsDevExpress.AIIntegration.OpenAI (required if you use the WinForms Chat control with OpenAI.Assistant)DevExpress.Win.Design (enables design-time features for DevExpress UI controls)DevExpress AI-powered extensions operate within an AIExtensionsContainerDesktop container. This container manages all registered AI clients so that DevExpress UI controls can automatically leverage AI services.
The following code snippet registers an OpenAI client:
using Microsoft.Extensions.AI;
using DevExpress.AIIntegration;
internal static class Program {
[STAThread]
static void Main() {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
IChatClient openAIChatClient = new OpenAI.OpenAIClient(OpenAIKey).GetChatClient(Model)
.AsIChatClient();
AIExtensionsContainerDesktop.Default.RegisterChatClient(openAIChatClient);
// Uncomment the following line if your project targets the .NET Framework and
// you create AI-powered behaviors in code.
// DevExpress.AIIntegration.WinForms.BehaviorInitializer.Initialize();
Application.Run(new Form1());
}
static string OpenAIKey { get { return Environment.GetEnvironmentVariable("OPENAI_API_KEY"); } }
static string Model { get { return "gpt-4o-mini"; } }
}
Imports Microsoft.Extensions.AI
Imports DevExpress.AIIntegration
Friend Module Program
<STAThread>
Sub Main()
Application.EnableVisualStyles()
Application.SetCompatibleTextRenderingDefault(False)
Dim openAIChatClient As IChatClient = New OpenAI.OpenAIClient(OpenAIKey).GetChatClient(Model).AsIChatClient()
AIExtensionsContainerDesktop.Default.RegisterChatClient(openAIChatClient)
' Uncomment the following line if your project targets the .NET Framework and
' you create AI-powered behaviors in code.
' DevExpress.AIIntegration.WinForms.BehaviorInitializer.Initialize()
Application.Run(New Form1())
End Sub
Private ReadOnly Property OpenAIKey() As String
Get
Return Environment.GetEnvironmentVariable("OPENAI_API_KEY")
End Get
End Property
Private ReadOnly Property Model As String
Get
Return "gpt-4o-mini"
End Get
End Property
End Module
The following code snippet registers an Azure OpenAI client:
using Microsoft.Extensions.AI;
using DevExpress.AIIntegration;
internal static class Program {
[STAThread]
static void Main() {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
IChatClient azureChatClient = new Azure.AI.OpenAI.AzureOpenAIClient(new Uri(AzureOpenAIEndpoint),
new System.ClientModel.ApiKeyCredential(AzureOpenAIKey))
.GetChatClient(ModelId).AsIChatClient();
AIExtensionsContainerDesktop.Default.RegisterChatClient(azureChatClient);
// Uncomment the following line if your project targets the .NET Framework and
// you create AI-powered behaviors in code.
// DevExpress.AIIntegration.WinForms.BehaviorInitializer.Initialize();
Application.Run(new Form1());
}
static string AzureOpenAIEndpoint { get { return Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT"); } }
static string AzureOpenAIKey { get { return Environment.GetEnvironmentVariable("AZURE_OPENAI_APIKEY"); } }
static string ModelId { get { return "gpt-4o-mini"; } }
}
Imports Microsoft.Extensions.AI
Imports DevExpress.AIIntegration
Friend Module Program
<STAThread>
Sub Main()
Application.EnableVisualStyles()
Application.SetCompatibleTextRenderingDefault(False)
Dim azureChatClient As IChatClient = New Azure.AI.OpenAI.AzureOpenAIClient(New Uri(AzureOpenAIEndpoint),
New System.ClientModel.ApiKeyCredential(AzureOpenAIKey)).
GetChatClient(ModelId).AsIChatClient()
AIExtensionsContainerDesktop.Default.RegisterChatClient(azureChatClient)
' Uncomment the following line if your project targets the .NET Framework and
' you create AI-powered behaviors in code.
' DevExpress.AIIntegration.WinForms.BehaviorInitializer.Initialize()
Application.Run(New Form1())
End Sub
Private ReadOnly Property AzureOpenAIEndpoint As String
Get
Return Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT")
End Get
End Property
Private ReadOnly Property AzureOpenAIKey As String
Get
Return Environment.GetEnvironmentVariable("AZURE_OPENAI_APIKEY")
End Get
End Property
Private ReadOnly Property ModelId As String
Get
Return "gpt-4o-mini"
End Get
End Property
End Module
Install the connector package for the AI service. This example uses Microsoft.SemanticKernel.Connectors.Google.
using Microsoft.Extensions.AI;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;
using Microsoft.SemanticKernel.Connectors.Google;
using DevExpress.AIIntegration;
internal static class Program {
[STAThread]
static void Main() {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var builder = Kernel.CreateBuilder().AddGoogleAIGeminiChatCompletion("YOUR_MODEL_ID", "YOUR_API_KEY", GoogleAIVersion.V1_Beta);
Kernel kernel = builder.Build();
IChatClient googleChatClient = kernel.GetRequiredService<IChatCompletionService>().AsChatClient();
AIExtensionsContainerDesktop.Default.RegisterChatClient(googleChatClient);
// Uncomment the following line if your project targets the .NET Framework and
// you create AI-powered behaviors in code.
// DevExpress.AIIntegration.WinForms.BehaviorInitializer.Initialize();
Application.Run(new Form1());
}
}
Imports Microsoft.Extensions.AI
Imports Microsoft.SemanticKernel
Imports Microsoft.SemanticKernel.ChatCompletion
Imports Microsoft.SemanticKernel.Connectors.Google
Imports DevExpress.AIIntegration;
Friend Module Program
<STAThread>
Sub Main()
Application.EnableVisualStyles()
Application.SetCompatibleTextRenderingDefault(False)
Dim builder = Kernel.CreateBuilder().AddGoogleAIGeminiChatCompletion("YOUR_MODEL_ID", "YOUR_API_KEY", GoogleAIVersion.V1_Beta)
Dim kernel As Kernel = builder.Build()
Dim googleChatClient As IChatClient = kernel.GetRequiredService(Of IChatCompletionService)().AsChatClient()
AIExtensionsContainerDesktop.Default.RegisterChatClient(googleChatClient)
' Uncomment the following line if your project targets the .NET Framework and
' you create AI-powered behaviors in code.
' DevExpress.AIIntegration.WinForms.BehaviorInitializer.Initialize()
Application.Run(New Form1())
End Sub
End Module
The following code snippet registers an Ollama client:
using OllamaSharp;
using Microsoft.Extensions.AI;
using DevExpress.AIIntegration;
internal static class Program {
[STAThread]
static void Main() {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
IChatClient asChatClient = new OllamaApiClient(new Uri("http://localhost:11434/"), "MODEL_NAME");
AIExtensionsContainerDesktop.Default.RegisterChatClient(asChatClient);
// Uncomment the following line if your project targets the .NET Framework and
// you create AI-powered behaviors in code.
// DevExpress.AIIntegration.WinForms.BehaviorInitializer.Initialize();
Application.Run(new Form1());
}
}
Imports OllamaSharp
Imports Microsoft.Extensions.AI
Imports DevExpress.AIIntegration
Friend Module Program
<STAThread>
Sub Main()
Application.EnableVisualStyles()
Application.SetCompatibleTextRenderingDefault(False)
Dim asChatClient As IChatClient = New OllamaApiClient(New Uri("http://localhost:11434/"), "MODEL_NAME")
AIExtensionsContainerDesktop.Default.RegisterChatClient(asChatClient)
' Uncomment the following line if your project targets the .NET Framework and
' you create AI-powered behaviors in code.
' DevExpress.AIIntegration.WinForms.BehaviorInitializer.Initialize()
Application.Run(New Form1())
End Sub
End Module
The following code snippet registers a Foundry Local chat client. Foundry Local runs AI models directly on the local device. It does not require cloud services or API keys. The SDK downloads and manages models automatically and exposes an OpenAI-compatible interface.
Note
Users do not need to install the Foundry Local CLI. The SDK is self-contained and handles model downloads and execution independently.
using DevExpress.AIIntegration;
using Microsoft.AI.Foundry.Local;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.Logging;
using OpenAI;
using System;
using System.ClientModel;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace DXApplication {
internal static class Program {
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
internal static void Main() {
// Create a LoggerFactory and configure console logging.
using var loggerFactory = LoggerFactory.Create(builder => {
builder
// Set log level based on environment variable, fallback to Information
.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Information)
.AddSimpleConsole(options => { options.SingleLine = true; options.TimestampFormat = "HH:mm:ss "; });
});
// Specify the model name.
string modelName = "phi-4-mini";
// Register a Foundry Local client.
RegisterFoundryLocalClient(modelName, loggerFactory).GetAwaiter();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
async static Task RegisterFoundryLocalClient(string modelAlias, ILoggerFactory loggerFactory) {
// Initialize the Foundry Local manager.
var config = new Configuration {
AppName = "DevExpressAIApp",
LogLevel = Microsoft.AI.Foundry.Local.LogLevel.Information,
Web = new Configuration.WebService() {
Urls = "http://127.0.0.1:52495"
}
};
// Create a named logger.
var logger = loggerFactory.CreateLogger("FoundryLocal");
await FoundryLocalManager.CreateAsync(config, logger, null);
var manager = FoundryLocalManager.Instance;
var catalog = await manager.GetCatalogAsync();
// Get the model from the catalog by alias.
var model = await catalog.GetModelAsync(modelAlias) ?? throw new Exception($"Model {modelAlias} not found");
// Check whether the model is cached and download it if required.
if (!await model.IsCachedAsync()) {
await model.DownloadAsync(progress => {
if (progress >= 100f) Console.WriteLine();
});
}
// Load the model.
await model.LoadAsync();
// Start the web service.
await manager.StartWebServiceAsync();
// OpenAIClient requires an ApiKeyCredential, but local Foundry server runs without credentials.
ApiKeyCredential key = new ApiKeyCredential("key_not_required");
// Create the OpenAI client that points to the Foundry Local web service.
OpenAIClient client = new OpenAIClient(key, new OpenAIClientOptions {
Endpoint = new Uri(config.Web.Urls + "/v1"),
});
// Get the chat client.
IChatClient chatClient = client.GetChatClient(model.Id).AsIChatClient();
AIExtensionsContainerDesktop.Default.RegisterChatClient(chatClient);
// Cleanup on exit.
Application.ApplicationExit += async (sender, e) => {
try {
chatClient.Dispose();
await model.UnloadAsync();
}
catch (Exception unloadEx) {
logger.LogWarning(unloadEx, "Error during model unload/cleanup.");
}
};
}
}
}
Imports DevExpress.AIIntegration
Imports Microsoft.AI.Foundry.Local
Imports Microsoft.Extensions.AI
Imports Microsoft.Extensions.Logging
Imports OpenAI
Imports System
Imports System.ClientModel
Imports System.Threading.Tasks
Imports System.Windows.Forms
Namespace DXApplication
Friend Module Program
''' <summary>
''' The main entry point for the application.
''' </summary>
<STAThread>
Sub Main()
' Create a LoggerFactory and configure console logging.
Using loggerFactory = LoggerFactory.Create(
Sub(builder)
builder _
.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Information) _
.AddSimpleConsole(
Sub(options)
options.SingleLine = True
options.TimestampFormat = "HH:mm:ss "
End Sub)
End Sub)
' Specify the model name.
Dim modelName As String = "phi-4-mini"
' Register a Foundry Local client.
RegisterFoundryLocalClient(modelName, loggerFactory).GetAwaiter()
Application.EnableVisualStyles()
Application.SetCompatibleTextRenderingDefault(False)
Application.Run(New Form1())
End Using
End Sub
Private Async Function RegisterFoundryLocalClient(
modelAlias As String,
loggerFactory As ILoggerFactory) As Task
' Initialize the Foundry Local manager.
Dim config As New Configuration With {
.AppName = "DevExpressAIApp",
.LogLevel = Microsoft.AI.Foundry.Local.LogLevel.Information,
.Web = New Configuration.WebService With {
.Urls = "http://127.0.0.1:52495"
}
}
' Create a named logger.
Dim logger = loggerFactory.CreateLogger("FoundryLocal")
Await FoundryLocalManager.CreateAsync(config, logger, Nothing)
Dim manager = FoundryLocalManager.Instance
Dim catalog = Await manager.GetCatalogAsync()
' Get the model from the catalog by alias.
Dim model = Await catalog.GetModelAsync(modelAlias)
If model Is Nothing Then
Throw New Exception($"Model {modelAlias} not found")
End If
' Check whether the model is cached and download it if required.
If Not Await model.IsCachedAsync() Then
Await model.DownloadAsync(
Sub(progress)
If progress >= 100.0F Then
Console.WriteLine()
End If
End Sub)
End If
' Load the model.
Await model.LoadAsync()
' Start the web service.
Await manager.StartWebServiceAsync()
' OpenAIClient requires an ApiKeyCredential, but local Foundry server runs without credentials.
Dim key As New ApiKeyCredential("key_not_required")
' Create the OpenAI client that points to the Foundry Local web service.
Dim client As New OpenAIClient(
key,
New OpenAIClientOptions With {
.Endpoint = New Uri(config.Web.Urls & "/v1")
})
' Get the chat client.
Dim chatClient As IChatClient =
client.GetChatClient(model.Id).AsIChatClient()
AIExtensionsContainerDesktop.Default.RegisterChatClient(chatClient)
' Cleanup on exit.
AddHandler Application.ApplicationExit,
Async Sub(sender, e)
Try
chatClient.Dispose()
Await model.UnloadAsync()
Catch unloadEx As Exception
logger.LogWarning(unloadEx, "Error during model unload/cleanup.")
End Try
End Sub
End Function
End Module
End Namespace
See the following resources for additional information:
The following code snippet registers an ONNX Runtime GenAI chat client. ONNX Runtime runs optimized AI models directly on the local device. It does not require cloud services.
Note
ONNX models are not bundled with the SDK. You must download an ONNX model to the local machine before use. You can obtain ONNX models from Hugging Face or ONNX Model Zoo. You can also convert custom models with ONNX converter tools.
using DevExpress.AIIntegration;
using Microsoft.Extensions.AI;
using Microsoft.ML.OnnxRuntimeGenAI;
// Define the path to the ONNX model directory.
var modelPath = "..\\..\\models\\cpu_and_mobile\\cpu-int4-rtn-block-32-acc-level-4\\";
// The path for Linux-based systems
// var modelPath = "../../models/cpu_and_mobile/cpu-int4-rtn-block-32-acc-level-4/";
// Verify that the model directory exists.
if (!Directory.Exists(modelPath)) {
MessageBox.Show("Model files not found. Ensure that the model files exist at the specified path.");
return;
}
// Create the model configuration.
using var config = new Config(modelPath);
// Initialize the ONNX model.
using var model = new Model(config);
// Create an ONNX Runtime chat client.
using var onnxChatClient = new OnnxRuntimeGenAIChatClient(model);
// Configure chat client options.
using var chat = onnxChatClient.AsBuilder().ConfigureOptions(
x => x.MaxOutputTokens = 4096
).Build();
// Register the chat client.
AIExtensionsContainerDesktop.Default.RegisterChatClient(chat);
// Handle application exit and unload the model.
Application.ApplicationExit += (sender, e) => {
chat?.Dispose();
onnxChatClient?.Dispose();
model?.Dispose();
config?.Dispose();
};
Imports DevExpress.AIIntegration
Imports Microsoft.Extensions.AI
Imports Microsoft.ML.OnnxRuntimeGenAI
Imports System.IO
Imports System.Windows.Forms
Module Program
Sub Main()
' Define the path to the ONNX model directory.
Dim modelPath As String = "..\..\models\cpu_and_mobile\cpu-int4-rtn-block-32-acc-level-4\"
' The path for Linux-based systems
' Dim modelPath As String = "../../models/cpu_and_mobile/cpu-int4-rtn-block-32-acc-level-4/"
' Verify that the model directory exists.
If Not Directory.Exists(modelPath) Then
MessageBox.Show("Model files not found. Ensure that the model files exist at the specified path.")
Return
End If
' Create the model configuration.
Using config As New Config(modelPath)
' Initialize the ONNX model.
Using model As New Model(config)
' Create an ONNX Runtime chat client.
Using onnxChatClient As New OnnxRuntimeGenAIChatClient(model)
' Configure chat client options.
Dim chat =
onnxChatClient _
.AsBuilder() _
.ConfigureOptions(
Sub(x)
x.MaxOutputTokens = 4096
End Sub) _
.Build()
' Register the chat client.
AIExtensionsContainerDesktop.Default.RegisterChatClient(chat)
' Handle application exit and unload the model.
AddHandler Application.ApplicationExit,
Sub(sender, e)
chat?.Dispose()
onnxChatClient?.Dispose()
model?.Dispose()
config?.Dispose()
End Sub
Application.Run()
End Using
End Using
End Using
End Sub
End Module
Tip
MaxOutputTokens based on the model’s capabilities and your application’s requirements.See the following resources for additional information:
AI Assistant extensions allow you to enhance the way your users interact with and manage text content with AI-powered precision. These extensions leverage advanced natural language processing (NLP) technologies to provide automated, intelligent text manipulation capabilities directly within your Windows Forms applications.
AI-powered options include:
Applies to:
See the following help topic for additional information: AI Assistant Extensions.
The AI-powered “Explain Formula” extension generates a detailed explanation of the formula used in a worksheet cell in the DevExpress Spreadsheet control.
See the following help topic for additional information: Explain Formula.
The AI-powered “Generate Image Description” extension generates the description for the image in DevExpress WinForms Spreadsheet and Rich Text Edit controls.
Play the following animation to see how the AI-powered “Generate Image Description” extension in a WinForms Rich Text Editor generates Alt text for an image:
See the following help topic for additional information: Generate Image Description.
The AI-powered “Prompt to Expression” extension converts natural language into valid filter and unbound column expressions for data-aware WinForms controls. Instead of writing complex expressions, users describe the desired logic in plain text:
Sample Filter Expression_Display orders expected to arrive within 7 days.Sample Unbound Column Expression_Compute total amount.
The system sends the prompt to the configured AI service, which generates a valid expression for the control. The Expression Editor or Filter Editor displays and validates the result immediately.
Run Demo: Prompt to Expression
See the following help topic for more information: Prompt to Expression.
The AI-powered “Smart Autocomplete” feature intelligently predicts and suggests words or phrases based on the user’s current input. As you type, the AI model analyzes the context of the text and makes relevant suggestions in real time.
Applies to:
See the following help topic for additional information: Smart Autocomplete.
“SmartPaste” is an AI-powered feature that transforms the traditional copy-and-paste process into a smarter, more efficient tool. Designed to improve productivity, SmartPaste analyzes the content you copy and intelligently assigns the right values to the appropriate fields or row cells in the DevExpress Data Grid and LayoutControl-driven forms.
Play the following animation to see how “SmartPaste” works:
Applies to:
See the following help topic for additional information: Smart Paste.
“Smart Search” works alongside the traditional search algorithms to offer a more powerful and user-friendly search experience. It offers results that are more aligned with what the user is seeking, even if the input contains misspellings.
Play the following animation to see how AI-powered smart search works in the DevExpress WinForms Ribbon control:
Applies to:
See the following help topic for additional information: Smart Search.
Semantic search enables users to locate relevant data quickly and accurately within large datasets. Unlike standard keyword-based search, semantic search leverages Natural Language Processing (NLP) to analyze search queries beyond exact keyword matching.
Semantic search uses an embedding generator to convert text into numerical vector representations. Vectors are stored in a vector database. When a user enters a search query, the search engine computes similarity scores between the query vector and stored data vectors to return the most relevant results.
Run Demo: Semantic Search - Grid Control
Applies to:
See the following help topic for additional information: Semantic Search.
You can create custom extensions based on DevExpress AI-powered extensions. See the following help topic for additional information and examples: Create Custom AI-powered Extensions.
Note
The AI Chat 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.
The AI Chat Control (AIChatControl) allows you to incorporate an interactive, Copilot-inspired chat-based UI within your WinForms application. The DevExpress AI Chat Control (AIChatControl) can only be used in Windows Forms applications that target the .NET 8+ framework.
Features include:
See the following help topic for additional information: AI Chat Control.