Skip to main content
All docs
V25.1
  • Custom AI-powered Extensions

    • 3 minutes to read

    The following example creates a custom AI-powered extension (“AuthoredStyleExtension”) and integrates it into the DevExpress Rich Text Editor.

    Custom AI-powered Extension - WinForms Rich Text Editor, DevExpress

    Register AI Client

    See the following help topic for information on required NuGet packages and system requirements: Register an 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 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"; } }
    }
    

    Create an Extension

    The AuthoredStyleExtension is based on the DevExpress ChangeStyleExtension. The example overrides the GetSystemPrompt method to customize the prompt:

    using DevExpress.AIIntegration.Extensions;
    
    public class AuthoredStyleExtension : ChangeTextExtension<AuthoredStyleRequest> {
        public AuthoredStyleExtension(IServiceProvider serviceProvider) : base(serviceProvider) { }
        protected override string GetSystemPrompt(AuthoredStyleRequest request) {
            return String.Format("Rewrite this text in the {0} style", request.Author);
        }
    }
    
    public class AuthoredStyleRequest : TextRequest {
        public AuthoredStyleRequest(string Author, string Text) : base(Text) {
            this.Author = Author;
        }
        public string Author { get; set; }
    }
    

    Integrate an AI-powered Extension into a Rich Text Editor

    Register the AuthoredStyleExtension and handle the RichEditControl.PopupMenuShowing event to display a submenu (“Authored Style”) in the popup menu:

    using DevExpress.AIIntegration;
    using DevExpress.AIIntegration.WinForms;
    using DevExpress.Utils.Menu;
    using DevExpress.XtraBars.Ribbon;
    using DevExpress.XtraRichEdit.API.Native;
    
    public partial class Form1 : RibbonForm {
        public Form1() {
            InitializeComponent();
    
            var defaultContainer = AIExtensionsContainerDesktop.Default;
            defaultContainer.Register<AuthoredStyleRequest, AuthoredStyleExtension>();
    
            string menuCaption = "Authored Style";
            richEditControl.PopupMenuShowing += (s, e) => {
                var menuItem = e.Menu.Items.FirstOrDefault(x => x.Caption == menuCaption) as DXSubMenuItem;
                if (menuItem == null) {
                    menuItem = new DXSubMenuItem(menuCaption);
                    string[] authors = ["Mark Twain", "Ernest Hemingway", "Maya Angelou"];
                    foreach (string author in authors) {
                        menuItem.Items.Add(new DXMenuItem(author, async (ss, ee) => {
                            var extension = (AuthoredStyleExtension)defaultContainer.GetExtension(typeof(AuthoredStyleRequest));
                            DocumentRange selection = richEditControl.Document.Selection;
                            var request = new AuthoredStyleRequest(author, richEditControl.Document.GetText(selection));
                            string result = await AIOverlayForm.Execute(richEditControl, extension, request);
                            richEditControl.Document.Replace(selection, result);
                        }));
                    }
                    e.Menu.Items.Add(menuItem);
                }
            };
        }
    }
    

    Run Demo: Create Custom Extension in MemoEdit

    See Also