<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Calvince Moth</title>
    <description>The latest articles on DEV Community by Calvince Moth (@calvinceawitim).</description>
    <link>https://dev.to/calvinceawitim</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2291171%2F848b22b8-80f6-4883-bc8b-17a7faec0136.jpg</url>
      <title>DEV Community: Calvince Moth</title>
      <link>https://dev.to/calvinceawitim</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/calvinceawitim"/>
    <language>en</language>
    <item>
      <title>Build an AI Content Creation App in Blazor with AI AssistView</title>
      <dc:creator>Calvince Moth</dc:creator>
      <pubDate>Mon, 13 Apr 2026 12:01:28 +0000</pubDate>
      <link>https://dev.to/syncfusion/build-an-ai-content-creation-app-in-blazor-with-ai-assistview-30mc</link>
      <guid>https://dev.to/syncfusion/build-an-ai-content-creation-app-in-blazor-with-ai-assistview-30mc</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Build an AI-assisted content creation app in Blazor using Syncfusion AI AssistView as the chat surface. Add Blog/KB modes with different system instructions, suggestions, and output templates, then layer in file attachments, speech-to-text, and text-to-speech via JS interop.&lt;/p&gt;

&lt;p&gt;If you’ve ever tried to use a single “write me content” prompt for everything, you’ve seen the problem: blog drafts turn into support docs, and KB articles start reading like marketing copy. The UI is fine, the instructions and structure are what break down.&lt;/p&gt;

&lt;p&gt;In this walkthrough, you’ll build a small Blazor Web App (.NET 10) that uses the &lt;a href="https://www.syncfusion.com/blazor-components/blazor-ai-assistview" rel="noopener noreferrer"&gt;Syncfusion &lt;strong&gt;&lt;sup&gt;®&lt;/sup&gt;&lt;/strong&gt; Blazor AI AssistView&lt;/a&gt; component as the chat surface and routes requests through a mode-aware prompt builder so your output stays &lt;strong&gt;Blog&lt;/strong&gt; or &lt;strong&gt;Knowledge Base&lt;/strong&gt; consistently.&lt;/p&gt;

&lt;p&gt;Before getting started with this implementation, make sure you’re familiar with the baseline setup (Syncfusion packages and AssistView rendering) described in the official &lt;a href="https://blazor.syncfusion.com/documentation/ai-assistview/getting-started-webapp" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s new in the content creation app
&lt;/h2&gt;

&lt;p&gt;Here’s what we’re adding on top of the getting-started baseline:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Blog vs KB modes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Blogs and KB articles have different success criteria. The mode switch lets you make those differences explicit, so the model stops guessing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Mode-aware prompting&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead of sending &lt;code&gt;args.Prompt&lt;/code&gt; directly, we’ll build a final prompt that includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;shared rules (markdown, accuracy, etc.)&lt;/li&gt;
&lt;li&gt;a mode-specific output template&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the part that typically improves consistency the most.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Real workflow features&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Attachments&lt;/strong&gt;: bring your own reference doc/log/draft.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Speech-to-text&lt;/strong&gt;: capture ideas faster.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Text-to-speech&lt;/strong&gt;: review long output hands-free.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clear prompts&lt;/strong&gt;: reset and start a fresh session.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How it works (architecture in one minute)
&lt;/h2&gt;

&lt;p&gt;The pattern is simple and scales well:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;UI (&lt;code&gt;AI AssistView&lt;/code&gt;) collects the user prompt.&lt;/li&gt;
&lt;li&gt;A mode selector (Blog vs KB) chooses a configuration:

&lt;ul&gt;
&lt;li&gt;system instruction (high-level role + constraints)&lt;/li&gt;
&lt;li&gt;prompt suggestions (starter prompts that match the mode)&lt;/li&gt;
&lt;li&gt;output template (the structure you want back)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Your &lt;a href="https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.InteractiveChat.SfAIAssistView.html#Syncfusion_Blazor_InteractiveChat_SfAIAssistView_PromptRequested" rel="noopener noreferrer"&gt;PromptRequested&lt;/a&gt; handler builds a final prompt:

&lt;ul&gt;
&lt;li&gt;shared rules (Markdown, accuracy)&lt;/li&gt;
&lt;li&gt;mode template (Blog vs KB outline)&lt;/li&gt;
&lt;li&gt;user request&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;You call Gemini (or any model) and return the response via &lt;a href="https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.InteractiveChat.SfAIAssistView.html#Syncfusion_Blazor_InteractiveChat_SfAIAssistView_UpdateResponseAsync_System_String_" rel="noopener noreferrer"&gt;UpdateResponseAsync&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is a practical midpoint between raw chat and a full workflow engine.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F04%2FAfter-selecting-a-prompt-from-the-prompt-suggestions.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F04%2FAfter-selecting-a-prompt-from-the-prompt-suggestions.png" alt="&amp;lt;alt-text&amp;gt;" width="800" height="395"&gt;&lt;/a&gt;&lt;br&gt;After selecting a prompt from the prompt suggestions
  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F04%2FAfter-scrolling-through-the-end-of-the-AI-response-output.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F04%2FAfter-scrolling-through-the-end-of-the-AI-response-output.png" alt="&amp;lt;alt-text&amp;gt;" width="800" height="391"&gt;&lt;/a&gt;&lt;br&gt;After scrolling through the end of the AI response output
  &lt;/p&gt;

&lt;p&gt;That gives you a working AssistView UI. But if you keep one generic instruction and one mixed-suggestion list, users will get an inconsistent output structure. The rest of this post is about fixing that by making &lt;code&gt;mode&lt;/code&gt; a first-class concept.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://dotnet.microsoft.com/en-us/download/dotnet/10.0" rel="noopener noreferrer"&gt;.NET 10 SDK&lt;/a&gt; (or your target SDK)&lt;/li&gt;
&lt;li&gt;A Blazor Web App with Syncfusion Blazor configured&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/googleapis/dotnet-genai" rel="noopener noreferrer"&gt;Google.GenAI&lt;/a&gt; configured with an API key (&lt;a href="https://blazor.syncfusion.com/documentation/ai-assistview/ai-integrations/gemini-integration" rel="noopener noreferrer"&gt;Gemini&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Browser permission for microphone + speech synthesis (for voice features)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With the groundwork in place, let’s dive into the step‑by‑step implementation&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Add a Blog/KB mode model
&lt;/h3&gt;

&lt;p&gt;Create a mode enum and a config object:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;ContentMode&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Blog&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;KnowledgeBase&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;sealed&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ModeConfig&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;required&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;DisplayName&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;init&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;required&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;SystemInstruction&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;init&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;required&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Suggestions&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;init&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then define your mode configs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;ContentMode&lt;/span&gt; &lt;span class="n"&gt;mode&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ContentMode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Blog&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;Dictionary&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ContentMode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ModeConfig&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;modes&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ContentMode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Blog&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ModeConfig&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;DisplayName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Blog"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;SystemInstruction&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;@"You are an expert content creator. Generate a developer blog post with clear headings, short paragraphs, and actionable steps. End with 8 FAQs."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;Suggestions&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s"&gt;"Generate a blog post outline on sustainable energy."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"Create a draft blog introduction about Blazor development."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"Suggest SEO keywords for a tech blog on AI."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"Rewrite this section to be more concise."&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ContentMode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;KnowledgeBase&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ModeConfig&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;DisplayName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"KB"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;SystemInstruction&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;@"You are an expert support writer. Generate a developer knowledge base article with Summary, Environment, Symptoms, Resolution steps, and Troubleshooting. End with 8 FAQs."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;Suggestions&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s"&gt;"Write a KB article on troubleshooting network issues."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"Draft a KB: 'App fails to start' with resolution steps."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"Create a troubleshooting checklist for intermittent timeouts."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"Summarize the likely root causes and next diagnostics."&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;ModeConfig&lt;/span&gt; &lt;span class="n"&gt;CurrentMode&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;modes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Wire mode suggestions into AI AssistView
&lt;/h3&gt;

&lt;p&gt;Point &lt;code&gt;AssistView&lt;/code&gt; at the current mode’s prompt suggestion list:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;SfAIAssistView&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;ref=&lt;/span&gt;&lt;span class="s"&gt;"assistView"&lt;/span&gt;
                &lt;span class="na"&gt;PromptSuggestions=&lt;/span&gt;&lt;span class="s"&gt;"CurrentMode.Suggestions"&lt;/span&gt;
                &lt;span class="na"&gt;PromptRequested=&lt;/span&gt;&lt;span class="s"&gt;"@PromptRequest"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/SfAIAssistView&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Add a simple mode selector (and clear chat on switch)
&lt;/h3&gt;

&lt;p&gt;The key detail here: clear prompts when switching modes. Otherwise, the previous &lt;code&gt;tone/structure&lt;/code&gt; can leak into the next request.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"width:155px; padding-bottom:20px; margin-left:34px"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"contentType"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Content Type&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;SfDropDownList&lt;/span&gt; &lt;span class="na"&gt;TValue=&lt;/span&gt;&lt;span class="s"&gt;"string"&lt;/span&gt;
                    &lt;span class="na"&gt;ID=&lt;/span&gt;&lt;span class="s"&gt;"contentType"&lt;/span&gt;
                    &lt;span class="na"&gt;TItem=&lt;/span&gt;&lt;span class="s"&gt;"ContentType"&lt;/span&gt;
                    &lt;span class="na"&gt;Placeholder=&lt;/span&gt;&lt;span class="s"&gt;"Select a content type"&lt;/span&gt;
                    &lt;span class="na"&gt;DataSource=&lt;/span&gt;&lt;span class="s"&gt;"@ContentTypes"&lt;/span&gt;
                    &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;bind-Index=&lt;/span&gt;&lt;span class="s"&gt;"@selectedContentTypeIndex"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;DropDownListFieldSettings&lt;/span&gt; &lt;span class="na"&gt;Value=&lt;/span&gt;&lt;span class="s"&gt;"ID"&lt;/span&gt;
                                   &lt;span class="na"&gt;Text=&lt;/span&gt;&lt;span class="s"&gt;"Text"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/DropDownListFieldSettings&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;DropDownListEvents&lt;/span&gt; &lt;span class="na"&gt;TValue=&lt;/span&gt;&lt;span class="s"&gt;"string"&lt;/span&gt;
                            &lt;span class="na"&gt;TItem=&lt;/span&gt;&lt;span class="s"&gt;"ContentType"&lt;/span&gt;
                            &lt;span class="na"&gt;ValueChange=&lt;/span&gt;&lt;span class="s"&gt;"OnValueChange"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/DropDownListEvents&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/SfDropDownList&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ContentType&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;ID&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;selectedContentTypeIndex&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ContentType&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ContentTypes&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Enum&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetValues&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ContentMode&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Cast&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ContentMode&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mode&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ContentType&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;ID&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;ToLower&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="n"&gt;Text&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToList&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;OnValueChange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ChangeEventArgs&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ContentType&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Enum&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TryParse&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ContentMode&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ItemData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;out&lt;/span&gt; &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;parsed&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;mode&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;parsed&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;// Prevent tone/structure “leakage” across modes&lt;/span&gt;
        &lt;span class="n"&gt;assistView&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="n"&gt;Prompts&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;Clear&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nf"&gt;StateHasChanged&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F04%2FBlog-and-KB-option-on-the-page.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F04%2FBlog-and-KB-option-on-the-page.png" alt="&amp;lt;alt-text&amp;gt;" width="272" height="236"&gt;&lt;/a&gt;&lt;br&gt;Blog and KB option on the page
  &lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Make SystemInstruction mode-aware
&lt;/h3&gt;

&lt;p&gt;In your &lt;code&gt;PromptRequested&lt;/code&gt; handler, set &lt;code&gt;SystemInstruction&lt;/code&gt; based on the mode:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;GenerateContentConfig&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;GenerateContentConfig&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;SystemInstruction&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Parts&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Part&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Part&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;CurrentMode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SystemInstruction&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 5: Add a structured prompt builder (shared rules + mode template)
&lt;/h3&gt;

&lt;p&gt;This is where output consistency really improves:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;BuildUserPrompt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;rawPrompt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;sharedRules&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"""
&lt;/span&gt;        &lt;span class="n"&gt;Use&lt;/span&gt; &lt;span class="n"&gt;Markdown&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
        &lt;span class="n"&gt;Use&lt;/span&gt; &lt;span class="n"&gt;headings&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="n"&gt;bullet&lt;/span&gt; &lt;span class="n"&gt;points&lt;/span&gt; &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="n"&gt;helpful&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
        &lt;span class="n"&gt;Be&lt;/span&gt; &lt;span class="n"&gt;accurate&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="n"&gt;avoid&lt;/span&gt; &lt;span class="n"&gt;making&lt;/span&gt; &lt;span class="n"&gt;up&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt; &lt;span class="n"&gt;behaviors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
        &lt;span class="s"&gt;""";
&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;modeTemplate&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mode&lt;/span&gt; &lt;span class="k"&gt;switch&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;ContentMode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Blog&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"""
&lt;/span&gt;            &lt;span class="n"&gt;Output&lt;/span&gt; &lt;span class="n"&gt;structure&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="n"&gt;Title&lt;/span&gt;
            &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="nf"&gt;Intro&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;direct&lt;/span&gt; &lt;span class="n"&gt;answer&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;bullets&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="n"&gt;Main&lt;/span&gt; &lt;span class="n"&gt;sections&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;H2&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="n"&gt;H3&lt;/span&gt; &lt;span class="n"&gt;headings&lt;/span&gt;
            &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="n"&gt;Common&lt;/span&gt; &lt;span class="n"&gt;mistakes&lt;/span&gt;
            &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="n"&gt;Conclusion&lt;/span&gt;
            &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="nf"&gt;FAQs&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="s"&gt;""",
&lt;/span&gt;        &lt;span class="n"&gt;ContentMode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;KnowledgeBase&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"""
&lt;/span&gt;            &lt;span class="n"&gt;Output&lt;/span&gt; &lt;span class="n"&gt;structure&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="n"&gt;Title&lt;/span&gt;
            &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="n"&gt;Summary&lt;/span&gt;
            &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="n"&gt;Environment&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="n"&gt;Applies&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt;
            &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="n"&gt;Symptoms&lt;/span&gt;
            &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="nf"&gt;Resolution&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;numbered&lt;/span&gt; &lt;span class="n"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="n"&gt;Troubleshooting&lt;/span&gt;
            &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="nf"&gt;FAQs&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="s"&gt;""",
&lt;/span&gt;        &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;$"""
&lt;/span&gt;        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;sharedRules&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;modeTemplate&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;User&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;rawPrompt&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="s"&gt;""";
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 6: Call Gemini with the final prompt
&lt;/h3&gt;

&lt;p&gt;Then call Gemini with the final prompt and update AssistView:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;PromptRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AssistViewPromptRequestedEventArgs&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;GenerateContentConfig&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;SystemInstruction&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Content&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Parts&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Part&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Part&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;CurrentMode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SystemInstruction&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="k"&gt;try&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;finalPrompt&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;BuildUserPrompt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Prompt&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GenerateContentAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"gemini-2.5-flash"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;finalPrompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;responseText&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Candidates&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Parts&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;assistView&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UpdateResponseAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;responseText&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Response&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;assistView&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Prompts&lt;/span&gt;&lt;span class="p"&gt;[^&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Response&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;$"Error: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Notes for reliability:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;BuildUserPrompt(...)&lt;/code&gt; is where you centralize formatting and guardrails.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;UpdateResponseAsync&lt;/code&gt;(…) pushes the model response back into the  &lt;strong&gt;Syncfusion Blazor AI AssistView&lt;/strong&gt;  UI.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This article was originally published at &lt;a href="https://www.syncfusion.com/blogs/post/blazor-ai-content-creation-app-structured-prompting" rel="noopener noreferrer"&gt;Syncfusion.com.&lt;/a&gt;&lt;/p&gt;

</description>
      <category>blazor</category>
      <category>dotnet</category>
      <category>dotnet10</category>
      <category>aiassistview</category>
    </item>
    <item>
      <title>Embed a Secure Inline PDF Viewer in React: No Downloads, Full Control</title>
      <dc:creator>Calvince Moth</dc:creator>
      <pubDate>Mon, 13 Apr 2026 11:42:24 +0000</pubDate>
      <link>https://dev.to/syncfusion/embed-a-secure-inline-pdf-viewer-in-react-no-downloads-full-control-3m08</link>
      <guid>https://dev.to/syncfusion/embed-a-secure-inline-pdf-viewer-in-react-no-downloads-full-control-3m08</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Every time a PDF opens in Acrobat, something breaks, users leave your app, analytics lose visibility, and security controls stop at the hard drive. What if PDFs never had to leave your UI at all? Embed PDF documents directly inside your app using the Syncfusion React PDF Viewer, lock down printing and downloads, tailor tools by user role, and capture real interaction data for audits and analytics, so PDFs stay part of your workflow, not an escape route.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stop downloading to view PDFs in your React app: There’s a better way
&lt;/h2&gt;

&lt;p&gt;Every time a PDF downloads and opens outside your app, you lose more than you expect:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;User attention&lt;/strong&gt;: The interface disappears.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Workflow continuity&lt;/strong&gt;: Navigation breaks and context are lost.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Control over sensitive documents&lt;/strong&gt;: Security rules stop applying.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Users click a document, the browser launches Acrobat or a native viewer, and your app is suddenly out of the picture. At that point, analytics go dark, and there’s no reliable way to know what the user did with the document.&lt;/p&gt;

&lt;p&gt;For modern React applications, especially internal portals, SaaS dashboards, and enterprise tools, this experience no longer works. Users expect PDFs to load instantly, stay in line, and remain secure without forced downloads or context switches.&lt;/p&gt;

&lt;p&gt;This guide shows how to embed a secure &lt;a href="https://www.syncfusion.com/pdf-viewer-sdk/react-pdf-viewer" rel="noopener noreferrer"&gt;PDF Viewer in React&lt;/a&gt; using &lt;a href="https://www.syncfusion.com/" rel="noopener noreferrer"&gt;Syncfusion&lt;sup&gt;®&lt;/sup&gt;&lt;/a&gt;, so documents render directly inside your app. You’ll learn how to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Disable printing and downloads.&lt;/li&gt;
&lt;li&gt;Configure role‑based toolbars.&lt;/li&gt;
&lt;li&gt;Track document interactions for audit and analytics purposes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The result:&lt;/strong&gt; PDFs become a controlled, first‑class part of your workflow, not something that pulls users out of it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why PDF downloads hurt your web app experience
&lt;/h2&gt;

&lt;p&gt;Considering a scenario, you’ve built a polished internal web portal with quick navigation and smooth UX. Then a user clicks a use-case file, and Chrome hands the PDF to Adobe Acrobat.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Your app just lost the user.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here’s why that single click silently damages your product metrics.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. It instantly breaks the user flow
&lt;/h3&gt;

&lt;p&gt;Switching from your app to a native desktop viewer is a &lt;strong&gt;hard context switch&lt;/strong&gt;. The user is suddenly in Acrobat’s viewer UI, with different controls, and no clear path back.&lt;/p&gt;

&lt;p&gt;For internal tools, HR portals, procurement systems, loan dashboards, and compliance apps, these broken flows don’t just frustrate users; they also undermine productivity. They create real operational drag.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. “Just download it” isn’t actually simple
&lt;/h3&gt;

&lt;p&gt;A “simple PDF download” is rarely simple:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Click -&amp;gt; download&lt;/strong&gt; → &lt;strong&gt;wait&lt;/strong&gt; → &lt;strong&gt;find file&lt;/strong&gt; → &lt;strong&gt;open&lt;/strong&gt; → &lt;strong&gt;read&lt;/strong&gt; → &lt;strong&gt;return to app&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Each extra step reduces completion rates, especially in onboarding, review, and approval workflows.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Mobile users get hit the hardest
&lt;/h3&gt;

&lt;p&gt;On mobile, PDF downloads often fail outright:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No default PDF reader.&lt;/li&gt;
&lt;li&gt;Files buried in downloads.&lt;/li&gt;
&lt;li&gt;Storage permission pop‑ups.&lt;/li&gt;
&lt;li&gt;Broken navigation back to the app.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In a mobile‑first enterprise world, downloads become a dead end.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Analytics &amp;amp; visibility disappear
&lt;/h3&gt;

&lt;p&gt;Once the PDF leaves your app, it disappears from your observability stack. You cannot reliably answer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Did they open it?&lt;/li&gt;
&lt;li&gt;Which pages did they read?&lt;/li&gt;
&lt;li&gt;Where did they stop?&lt;/li&gt;
&lt;li&gt;How long did the review take?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;An embedded viewer keeps those interactions inside your product so you can instrument them.&lt;/p&gt;

&lt;h2&gt;
  
  
  The hidden security &amp;amp; compliance risks of PDF downloads
&lt;/h2&gt;

&lt;p&gt;For enterprise teams, the problem with PDF downloads isn’t just bad UX; it’s a &lt;strong&gt;security and compliance liability&lt;/strong&gt; waiting to happen.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Downloaded PDFs are beyond your control
&lt;/h3&gt;

&lt;p&gt;Once a PDF is downloaded on a device:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can’t revoke access.&lt;/li&gt;
&lt;li&gt;You can’t prevent forwarding.&lt;/li&gt;
&lt;li&gt;You can’t audit distribution.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For organizations handling financial data, health records, legal contracts, or intellectual property, this isn’t a theoretical risk. It’s a &lt;strong&gt;compliance and security failure&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Sensitive data exposure risk increases
&lt;/h3&gt;

&lt;p&gt;Download-by-default often conflicts with internal governance and regulated requirements, including &lt;strong&gt;SOC 2, GDPR, HIPAA, PCI, and ISO&lt;/strong&gt; policies. Audits tend to focus on exactly this: where data goes and who can keep it.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. No access revocation
&lt;/h3&gt;

&lt;p&gt;Role changes, vendor offboarding, and account termination do not affect files that have already been downloaded. That is a permanent data leakage risk.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Vulnerable browser plugins
&lt;/h3&gt;

&lt;p&gt;Not every enterprise user is running an updated machine. Many are still using outdated browser PDF plugins, which are a known attack vector for maliciously crafted PDFs.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a fast, secure, inline PDF Viewer should include
&lt;/h2&gt;

&lt;p&gt;Before you pick up a solution, here’s what a production-ready embedded PDF viewer needs to deliver.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;View-only mode&lt;/strong&gt; with download/print disabled.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Role-based tools&lt;/strong&gt; with different toolbars for viewers, reviewers, and auditors.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Responsive UX&lt;/strong&gt; for desktops and mobile.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Progressive rendering&lt;/strong&gt; and smooth zoom/search on large PDFs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Event hooks&lt;/strong&gt; for analytics and audit trails.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Straightforward&lt;/strong&gt; and &lt;strong&gt;easy,&lt;/strong&gt; framework-friendly &lt;strong&gt;.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enterprise-ready controls&lt;/strong&gt; with access enforcement, logging strategy, and maintainability.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This article was originally published at &lt;a href="https://www.syncfusion.com/blogs/post/embed-secure-inline-pdf-viewer-react" rel="noopener noreferrer"&gt;Syncfusion.com.&lt;/a&gt;&lt;/p&gt;

</description>
      <category>pdf</category>
      <category>documentmanagement</category>
      <category>enterprisetools</category>
      <category>pdfviewer</category>
    </item>
    <item>
      <title>Convert Markdown to PDF in C# Using .NET Word Library</title>
      <dc:creator>Calvince Moth</dc:creator>
      <pubDate>Fri, 10 Apr 2026 11:42:27 +0000</pubDate>
      <link>https://dev.to/syncfusion/convert-markdown-to-pdf-in-c-using-net-word-library-2ee3</link>
      <guid>https://dev.to/syncfusion/convert-markdown-to-pdf-in-c-using-net-word-library-2ee3</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Convert Markdown to PDF in C# using .NET Word Library with just a few lines of code. Install the NuGet package, add namespaces, and run the conversion. Customize images with events, embed diagrams, or handle base64 streams. Ideal for documentation, eBooks, reports, and compliance workflows. Fast, accurate, and scalable for developer productivity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Markdown is loved by developers, but PDFs are trusted by everyone else
&lt;/h2&gt;

&lt;p&gt;Markdown is a popular choice for developers creating documentation and technical content.  But when it comes to sharing or archiving, PDF is the preferred format for its consistency and professionalism.&lt;/p&gt;

&lt;p&gt;In this blog, you’ll learn how to convert Markdown to PDF using &lt;strong&gt;C#&lt;/strong&gt; and ** ** &lt;a href="https://www.syncfusion.com/document-sdk/net-word-library" rel="noopener noreferrer"&gt;Syncfusion&lt;sup&gt;®&lt;/sup&gt; .NET Word Library&lt;/a&gt; with practical code examples, real-world use cases, and advanced customization tips.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why convert Markdown to PDF?
&lt;/h2&gt;

&lt;p&gt;Markdown is ideal for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Writing clean, readable documentation.&lt;/li&gt;
&lt;li&gt;Creating lightweight technical content.&lt;/li&gt;
&lt;li&gt;Collaborating in version-controlled environments.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;PDF is better for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Printing and sharing with non-technical users.&lt;/li&gt;
&lt;li&gt;Preserving formatting across devices.&lt;/li&gt;
&lt;li&gt;Archiving and compliance.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Bringing these formats together gives you both developer-friendly writing and professional-grade output. Next, let’s look at what you’ll need before starting the conversion process.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;.NET project (console app, service, or web app).&lt;/li&gt;
&lt;li&gt;A Markdown file (for example: Input.md).&lt;/li&gt;
&lt;li&gt;Syncfusion DocIO package.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to convert Markdown to PDF in C# using .NET Word Library
&lt;/h2&gt;

&lt;p&gt;Follow these steps to convert a Markdown file to PDF in C# using Syncfusion .NET Word Library:&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Install the Syncfusion DocIO NuGet package
&lt;/h3&gt;

&lt;p&gt;First, add the &lt;a href="https://www.nuget.org/packages/Syncfusion.DocIORenderer.Net.Core" rel="noopener noreferrer"&gt;Syncfusion.DocIORenderer.Net.Core&lt;/a&gt; NuGet package to your project, as shown below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F04%2Fimage001-1-768x342.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F04%2Fimage001-1-768x342.png" alt="&amp;lt;alt-text&amp;gt;" width="768" height="342"&gt;&lt;/a&gt;&lt;br&gt;Installing the Syncfusion  DocIO NuGet package
  &lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Add required namespaces
&lt;/h3&gt;

&lt;p&gt;Next, add the following namespaces to your file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Syncfusion.DocIO&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Syncfusion.DocIO.DLS&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Syncfusion.DocIORenderer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Syncfusion.Pdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Convert Markdown to PDF using C
&lt;/h3&gt;

&lt;p&gt;Open the Markdown stream in Word, then save it as a PDF.&lt;/p&gt;

&lt;p&gt;Here’s the code you need:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Open the Word document file stream.&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;FileStream&lt;/span&gt; &lt;span class="n"&gt;inputStream&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;FileStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Template.md"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;FileMode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Open&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;FileAccess&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReadWrite&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Load an existing Word document.&lt;/span&gt;
    &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;WordDocument&lt;/span&gt; &lt;span class="n"&gt;wordDocument&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;WordDocument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inputStream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;FormatType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Markdown&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Create an instance of DocIORenderer.&lt;/span&gt;
        &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DocIORenderer&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;DocIORenderer&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Convert Word document into PDF document.&lt;/span&gt;
            &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PdfDocument&lt;/span&gt; &lt;span class="n"&gt;pdfDocument&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ConvertToPDF&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;wordDocument&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="c1"&gt;// Save the PDF file to the file system.&lt;/span&gt;
                &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;FileStream&lt;/span&gt; &lt;span class="n"&gt;outputStream&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;FileStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Output.pdf"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;FileMode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;FileAccess&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReadWrite&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;pdfDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;outputStream&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By executing this code example, we will get output like in the following image.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F04%2Fimage003-768x375.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F04%2Fimage003-768x375.png" alt="&amp;lt;alt-text&amp;gt;" width="768" height="375"&gt;&lt;/a&gt;&lt;br&gt;Converting a Markdown document to PDF using C# and Syncfusion .NET Word Library
  &lt;/p&gt;

&lt;h2&gt;
  
  
  Advanced image customization options
&lt;/h2&gt;

&lt;p&gt;When converting Markdown to a PDF using the .NET Word Library, we have the flexibility to modify the images included in the input Markdown file.&lt;/p&gt;

&lt;h3&gt;
  
  
  Hook the ImageNodeVisited event
&lt;/h3&gt;

&lt;p&gt;We can download images listed as URLs in the Markdown file and insert them into the resulting Word document.&lt;/p&gt;

&lt;p&gt;You can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Replace placeholder images with client-specific branding.&lt;/li&gt;
&lt;li&gt;Embed diagrams from URLs or local folders.&lt;/li&gt;
&lt;li&gt;Handle base64-encoded images.&lt;/li&gt;
&lt;li&gt;Customize image streams using the &lt;code&gt;ImageNodeVisited&lt;/code&gt; event.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Refer to the following code example to achieve this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Open a file as a stream.&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;FileStream&lt;/span&gt; &lt;span class="n"&gt;fileStreamPath&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;FileStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Input.md"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;FileMode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Open&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;FileAccess&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Read&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;FileShare&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReadWrite&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Create a Word document instance.&lt;/span&gt;
    &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;WordDocument&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;WordDocument&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Hook the event to customize the image while importing Markdown.&lt;/span&gt;
        &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MdImportSettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ImageNodeVisited&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;MdImportSettings_ImageNodeVisited&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;// Open an existing Markdown file.&lt;/span&gt;
        &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fileStreamPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;FormatType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Markdown&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Create an instance of DocIORenderer.&lt;/span&gt;
        &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DocIORenderer&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;DocIORenderer&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Convert Word document into PDF document.&lt;/span&gt;
            &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PdfDocument&lt;/span&gt; &lt;span class="n"&gt;pdfDocument&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ConvertToPDF&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="c1"&gt;// Save the PDF file to the file system.&lt;/span&gt;
                &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;FileStream&lt;/span&gt; &lt;span class="n"&gt;outputStream&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;FileStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Output.pdf"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;FileMode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;FileAccess&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReadWrite&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;pdfDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;outputStream&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What this changes:&lt;/strong&gt; Now, every time DocIO encounters an image in Markdown, it calls your handler and gives you a chance to provide the actual image stream.&lt;/p&gt;

&lt;h3&gt;
  
  
  Implement the image handler
&lt;/h3&gt;

&lt;p&gt;The following C# code illustrates the use of the event handler to customize the image based on the source path.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;MdImportSettings_ImageNodeVisited&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="kt"&gt;object&lt;/span&gt; &lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Syncfusion&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Office&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Markdown&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MdImageNodeVisitedEventArgs&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Retrieve the image from the local machine file path and use it.&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Uri&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"Road-550.png"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ImageStream&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;FileStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Uri&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;FileMode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Open&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;// Retrieve the image from the website and use it.&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Uri&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;StartsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"https://"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;WebClient&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;WebClient&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="c1"&gt;// Download the image as a stream.&lt;/span&gt;
        &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;image&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;DownloadData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Uri&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Stream&lt;/span&gt; &lt;span class="n"&gt;stream&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;MemoryStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// Set the retrieved image from the input Markdown.&lt;/span&gt;
        &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ImageStream&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;// Retrieve the image from the Base64 string and use it.&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Uri&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;StartsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"data:image/"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;src&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Uri&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;startIndex&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IndexOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;","&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;src&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Substring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;startIndex&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;image&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Convert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromBase64String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Stream&lt;/span&gt; &lt;span class="n"&gt;stream&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;MemoryStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// Set the retrieved image from the input Markdown.&lt;/span&gt;
        &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ImageStream&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This article was originally published at &lt;a href="https://www.syncfusion.com/blogs/post/markdown-to-pdf-in-csharp-word-library" rel="noopener noreferrer"&gt;Syncfusion.com.&lt;/a&gt;&lt;/p&gt;

</description>
      <category>word</category>
      <category>dotnetdevelopment</category>
      <category>csharp</category>
      <category>documentprocessing</category>
    </item>
    <item>
      <title>Why .NET MAUI Popups Lag and How to Fix Performance Issues </title>
      <dc:creator>Calvince Moth</dc:creator>
      <pubDate>Fri, 10 Apr 2026 07:05:21 +0000</pubDate>
      <link>https://dev.to/syncfusion/why-net-maui-popups-lag-and-how-to-fix-performance-issues-1134</link>
      <guid>https://dev.to/syncfusion/why-net-maui-popups-lag-and-how-to-fix-performance-issues-1134</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Heavy popup content can block the UI thread and cause lag. Improve .NET MAUI Popup performance by reusing the popup view with ContentTemplate, loading data only when needed, virtualizing long lists, and keeping animations lightweight and fast.&lt;/p&gt;

&lt;p&gt;Your .NET MAUI app can feel fast until a popup opens with heavy UI. Then you see it: stuttering animations, slow scrolling, and a fragile feel that users notice immediately.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.syncfusion.com/maui-controls/maui-popup" rel="noopener noreferrer"&gt;Syncfusion &lt;strong&gt;&lt;sup&gt;®&lt;/sup&gt;&lt;/strong&gt;.NET MAUI Popup&lt;/a&gt; is designed for performance; however, when integrating popups with large datasets or complex layouts, you still need optimization to ensure a consistently smooth experience.&lt;/p&gt;

&lt;p&gt;In this blog, we will show you how to improve your app’s performance when using Syncfusion .NET MAUI Popup by applying the following proven techniques:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lazy initialization (create/load only when needed)&lt;/li&gt;
&lt;li&gt;Content caching (reuse the same view across opens)&lt;/li&gt;
&lt;li&gt;Virtualization for large lists&lt;/li&gt;
&lt;li&gt;Smooth, jank-free animations&lt;/li&gt;
&lt;li&gt;A safe content template lifecycle strategy&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With these strategies, you will achieve faster load times, reduced memory usage, and a seamless user experience across Android, iOS, Windows, and macOS.&lt;/p&gt;

&lt;h2&gt;
  
  
  Speed up .NET MAUI Popup: Best practices
&lt;/h2&gt;

&lt;p&gt;Let’s integrate &lt;a href="https://www.syncfusion.com/maui-controls/maui-popup" rel="noopener noreferrer"&gt;Syncfusion .NET MAUI Popup&lt;/a&gt; into a .NET MAUI app and apply these performance techniques.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; To get started with .NET MAUI Popup, check the official &lt;a href="https://help.syncfusion.com/maui/popup/getting-started" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario:&lt;/strong&gt; Product details popup with a large variants list.&lt;/p&gt;

&lt;p&gt;For this example, we’ll work with a sample application that shows a list of products. When the user taps a product, a popup displays product details, along with a potentially long list of variants (we simulate  &lt;strong&gt;1,000 variants&lt;/strong&gt; to stress-test performance).&lt;/p&gt;

&lt;p&gt;The goal is to reduce:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Tap-to-visible time&lt;/strong&gt; (how fast the popup appears).&lt;/li&gt;
&lt;li&gt;UI thread works during open/close animations.&lt;/li&gt;
&lt;li&gt;Memory churn caused by repeated view creation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can explore the complete sample implementation used in this walkthrough from the &lt;a href="https://github.com/SyncfusionExamples/How-to-do-performance-tuning-in-SfPopup" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; repository.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it works (what usually makes popups slow)
&lt;/h2&gt;

&lt;p&gt;Popups often feel &lt;strong&gt;slow&lt;/strong&gt; for a few predictable reasons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;View creation cost&lt;/strong&gt;: Building a complex visual tree each time you open the popup.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data loading cost&lt;/strong&gt;: Populating collections and binding large data at the wrong time (often right as the popup animates in).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;List rendering cost&lt;/strong&gt;: Creating UI containers for hundreds/thousands of rows without virtualization.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Animation contention&lt;/strong&gt;: Doing heavy work on the UI thread while the popup is animating.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The patterns below directly target these bottlenecks.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Cache and reuse the popup content via ContentTemplate
&lt;/h3&gt;

&lt;p&gt;We start by ensuring that the popup’s content is created only once and then reused. This caching approach prevents the framework from rebuilding the entire visual tree each time the popup opens, reducing unnecessary CPU work and memory use.&lt;/p&gt;

&lt;p&gt;By wrapping our _&lt;code&gt;popupView&lt;/code&gt; inside a &lt;code&gt;DataTemplate&lt;/code&gt; and assigning it to &lt;code&gt;ProductPopup.ContentTemplate&lt;/code&gt;, the first time the popup is shown, the Syncfusion .NET MAUI Popup reuses that same instance on every subsequent open instead of recreating it.&lt;/p&gt;

&lt;p&gt;Here’s how you can do it in code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;ProductDetailsPopupView&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;_popupView&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// This will hold our cached view&lt;/span&gt;
&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;MainViewModel&lt;/span&gt; &lt;span class="n"&gt;_viewModel&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;MainPage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;InitializeComponent&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;_viewModel&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;MainViewModel&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;BindingContext&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_viewModel&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;_viewModel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RequestOpenPopup&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_popupView&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Create the view only on the first open&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;_popupView&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ProductDetailsPopupView&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;BindingContext&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_viewModel&lt;/span&gt; &lt;span class="c1"&gt;// Keep the same ViewModel instance&lt;/span&gt;
            &lt;span class="p"&gt;};&lt;/span&gt;
            &lt;span class="c1"&gt;// Assign the cached view using a DataTemplate&lt;/span&gt;
            &lt;span class="n"&gt;ProductPopup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ContentTemplate&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;DataTemplate&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_popupView&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// ... (rest of the popup opening logic)&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above code example, &lt;code&gt;ContentTemplate&lt;/code&gt; returns the same cached view instance, so the UI tree is not recreated on every open. That’s a direct win for CPU and GC pressure.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Lazy initialize popup data only when the user taps (on-demand)
&lt;/h3&gt;

&lt;p&gt;Even with a cached view, you can still slow down your app by preparing data too early (for example, during page initialization). A better approach is to load popup data only when the user actually taps a product.&lt;/p&gt;

&lt;p&gt;In our sample, the product details and variant information are populated on demand, right before the popup opens. This keeps the app lightweight at startup while ensuring the popup always displays the correct information for the selected product.&lt;/p&gt;

&lt;p&gt;When &lt;code&gt;OnProductTapped&lt;/code&gt; is triggered, &lt;code&gt;InitializeDetails&lt;/code&gt; updates the popup’s data source, refreshes the variants list, and resets &lt;code&gt;SelectedVariant&lt;/code&gt; to null. This guarantees a consistent initial state, for example, keeping &lt;strong&gt;Add to Cart&lt;/strong&gt;  disabled until a variant is chosen.&lt;/p&gt;

&lt;p&gt;Code snippet to achieve this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;OnProductTapped&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Product&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;SelectedProduct&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nf"&gt;InitializeDetails&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Prepares popup data just before showing&lt;/span&gt;
    &lt;span class="n"&gt;RequestOpenPopup&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;Invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Signals MainPage to open the popup&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By updating the popup’s data only when it’s needed, you avoid unnecessary work during page load and ensure each product tap produces accurate, up-to-date details.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Virtualized list for large datasets
&lt;/h3&gt;

&lt;p&gt;Large lists inside a popup can seriously impact performance if the UI is forced to create a view for every row. Using a virtualized list ensures that only the visible items are rendered, while off‑screen containers are recycled as the user scrolls.&lt;/p&gt;

&lt;p&gt;In our sample, we display a large set of variants (simulated at &lt;code&gt;1,000 items&lt;/code&gt;) using the &lt;a href="https://www.syncfusion.com/maui-controls/maui-listview" rel="noopener noreferrer"&gt;Syncfusion .NET MAUI ListView&lt;/a&gt;. Since it’s virtualized by design, it creates UI elements only for items currently in view and reuses them as you scroll. This greatly reduces memory usage and keeps the popup responsive, even with large datasets.&lt;/p&gt;

&lt;p&gt;Below is the code you need:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;SfListView:SfListView&lt;/span&gt; &lt;span class="na"&gt;x:Name=&lt;/span&gt;&lt;span class="s"&gt;"VariantsList"&lt;/span&gt;
                       &lt;span class="na"&gt;Grid.Row=&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt;
                       &lt;span class="na"&gt;ItemsSource=&lt;/span&gt;&lt;span class="s"&gt;"{Binding Variants}"&lt;/span&gt;
                       &lt;span class="na"&gt;SelectedItem=&lt;/span&gt;&lt;span class="s"&gt;"{Binding SelectedVariant, Mode=TwoWay}"&lt;/span&gt;
                       &lt;span class="na"&gt;SelectionMode=&lt;/span&gt;&lt;span class="s"&gt;"Single"&lt;/span&gt; &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4: Fluid, jank-free animations
&lt;/h3&gt;

&lt;p&gt;Even small UI stalls become noticeable during animations. To keep the popup feeling fluid, let the animation run without competing for UI thread time, and fine-tune the animation settings to feel quick and natural.&lt;/p&gt;

&lt;p&gt;To ensure the popup opens and closes smoothly without stuttering, we rely on &lt;a href="https://help.syncfusion.com/maui/popup/getting-started" rel="noopener noreferrer"&gt;SfPopup’s&lt;/a&gt; built-in animations and avoid heavy operations during these critical UI moments.&lt;/p&gt;

&lt;p&gt;Setting &lt;a href="https://help.syncfusion.com/maui/popup/popup-animations#animation-duration" rel="noopener noreferrer"&gt;AnimationDuration&lt;/a&gt; to a short value (e.g., &lt;code&gt;180ms&lt;/code&gt;) and &lt;a href="https://help.syncfusion.com/maui/popup/popup-animations#animation-easing" rel="noopener noreferrer"&gt;Animation Easing&lt;/a&gt; to a curve like SinOut makes the Fade animation feel fast and natural, contributing significantly to a responsive user experience.&lt;/p&gt;

&lt;p&gt;Add this to your project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;syncfusion:SfPopup&lt;/span&gt; 
&lt;span class="err"&gt;…&lt;/span&gt;
    &lt;span class="na"&gt;AnimationMode=&lt;/span&gt;&lt;span class="s"&gt;"Fade"&lt;/span&gt; 
    &lt;span class="na"&gt;AnimationDuration=&lt;/span&gt;&lt;span class="s"&gt;"180"&lt;/span&gt; &lt;span class="err"&gt;&amp;lt;!--&lt;/span&gt; &lt;span class="err"&gt;A&lt;/span&gt; &lt;span class="err"&gt;quick,&lt;/span&gt; &lt;span class="err"&gt;snappy&lt;/span&gt; &lt;span class="err"&gt;duration&lt;/span&gt; &lt;span class="err"&gt;--&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    Easing="SinOut" &lt;span class="c"&gt;&amp;lt;!-- Enhances fluidity --&amp;gt;&lt;/span&gt;&amp;gt;
…
&lt;span class="nt"&gt;&amp;lt;/syncfusion:SfPopup&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This article was originally published at &lt;a href="https://www.syncfusion.com/blogs/post/speed-up-dotnet-maui-popup" rel="noopener noreferrer"&gt;Syncfusion.com.&lt;/a&gt;&lt;/p&gt;

</description>
      <category>dotnetmaui</category>
      <category>dotnetmauipopup</category>
      <category>crossplatformdevelop</category>
      <category>mobileui</category>
    </item>
    <item>
      <title>How to Protect Sheets and Workbooks in a React Spreadsheet</title>
      <dc:creator>Calvince Moth</dc:creator>
      <pubDate>Thu, 09 Apr 2026 13:19:27 +0000</pubDate>
      <link>https://dev.to/syncfusion/how-to-protect-sheets-and-workbooks-in-a-react-spreadsheet-nji</link>
      <guid>https://dev.to/syncfusion/how-to-protect-sheets-and-workbooks-in-a-react-spreadsheet-nji</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Want your React spreadsheets to feel rock‑solid without slowing your users down? Spreadsheet protection gives you the best of both worlds: you can lock down formulas, structure, and layouts while keeping key input cells open for editing. Use sheet protection + protectSettings to decide exactly what users can and can’t do, lockCells() to open just the ranges that matter, and workbook protection to stop sheet renaming, deleting, or moving.&lt;/p&gt;

&lt;p&gt;Handling sensitive or business-critical data in the &lt;a href="https://www.syncfusion.com/spreadsheet-editor-sdk/react-spreadsheet-editor" rel="noopener noreferrer"&gt;Syncfusion&lt;sup&gt;®&lt;/sup&gt; React Spreadsheet&lt;/a&gt;? Protecting sheets and workbooks ensures your templates, formulas, and inputs stay intact and tamper‑free.&lt;/p&gt;

&lt;p&gt;This guide walks you through:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When to protect a sheet vs. a workbook&lt;/li&gt;
&lt;li&gt;How to lock/unlock cells&lt;/li&gt;
&lt;li&gt;How to configure granular permissions&lt;/li&gt;
&lt;li&gt;How to apply read‑only mode&lt;/li&gt;
&lt;li&gt;Practical protection patterns for real‑world use cases&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Protection features in React Spreadsheet
&lt;/h2&gt;

&lt;p&gt;Syncfusion includes different layers of protection, each for different use cases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Workbook protection:&lt;/strong&gt; Prevents structural changes like:

&lt;ul&gt;
&lt;li&gt;Adding/removing sheets&lt;/li&gt;
&lt;li&gt;Renaming or hiding sheets&lt;/li&gt;
&lt;li&gt;Rearranging sheet order&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Sheet protection:&lt;/strong&gt; Restrict editing on the current sheet.
Used when:

&lt;ul&gt;
&lt;li&gt;You want formulas protected&lt;/li&gt;
&lt;li&gt;You want only certain cells to be editable&lt;/li&gt;
&lt;li&gt;You want users to view but not modify content&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Cell locking:&lt;/strong&gt; Lock selected cells or ranges while keeping others editable.&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Password protection:&lt;/strong&gt; Secure sheets with a password to prevent unauthorized changes.&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Selective permissions:&lt;/strong&gt; Control actions such as inserting/deleting cell data, formatting, resizing rows/columns, and inserting hyperlinks.&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Read-only mode:&lt;/strong&gt; Make cells non-editable to prevent modifications.&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Ready to lock it down? Explore advanced sheet-protection methods in Syncfusion React Spreadsheet to keep your data secure.&lt;/p&gt;

&lt;p&gt;Let’s dive in and see how you can lock sheets, secure cells, protect workbooks, and manage permissions with ease!&lt;/p&gt;

&lt;h2&gt;
  
  
  Protecting a sheet
&lt;/h2&gt;

&lt;p&gt;The protect sheet feature makes a sheet read-only, preventing edits unless you explicitly allow them. Enable sheet protection by setting the &lt;a href="https://ej2.syncfusion.com/react/documentation/api/spreadsheet/sheetModel/#isprotected" rel="noopener noreferrer"&gt;isProtected&lt;/a&gt; property to true (it is false by default).&lt;/p&gt;

&lt;p&gt;By default, these actions are disabled:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Selecting cells&lt;/li&gt;
&lt;li&gt;Editing cells&lt;/li&gt;
&lt;li&gt;Formatting rows, columns, or cells&lt;/li&gt;
&lt;li&gt;Inserting links&lt;/li&gt;
&lt;li&gt;Resizing, hiding rows/columns&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Customizing permissions with protectSettings
&lt;/h3&gt;

&lt;p&gt;The &lt;a href="https://ej2.syncfusion.com/react/documentation/api/spreadsheet/sheetModel/#protectsettings" rel="noopener noreferrer"&gt;protectSettings&lt;/a&gt; option lets you enable specific actions even when a sheet is protected. All options are disabled by default; set to true to enable.&lt;/p&gt;

&lt;p&gt;The available &lt;code&gt;protectSettings&lt;/code&gt; options are,&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Select locked cells:&lt;/strong&gt; Allow selecting locked cells for highlighting.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Select unlocked cells:&lt;/strong&gt; Allow selecting only unlocked cells.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Format cells:&lt;/strong&gt; Apply cell style like font, color, borders, number format, and conditional format.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Format rows:&lt;/strong&gt; Resize and hide Rows.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Format columns:&lt;/strong&gt; Resize and hide Columns.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Insert link:&lt;/strong&gt; Insert hyperlinks in unlocked cells.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, if &lt;code&gt;formatCells: true&lt;/code&gt; is set in &lt;code&gt;protectSettings&lt;/code&gt;, users can still apply styles, borders, and font or background colors even while the sheet is protected.&lt;/p&gt;

&lt;p&gt;This article was originally published at &lt;a href="https://www.syncfusion.com/blogs/post/protect-sheet-in-react-spreadsheet" rel="noopener noreferrer"&gt;Syncfusion.com.&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>excellikespreadsheet</category>
      <category>reactspreadsheet</category>
      <category>spreadsheet</category>
    </item>
    <item>
      <title>Add Digital Signatures to a WPF PDF Viewer with a Click-to-Place eSign Workflow</title>
      <dc:creator>Calvince Moth</dc:creator>
      <pubDate>Thu, 09 Apr 2026 11:44:02 +0000</pubDate>
      <link>https://dev.to/syncfusion/add-digital-signatures-to-a-wpf-pdf-viewer-with-a-click-to-place-esign-workflow-3ome</link>
      <guid>https://dev.to/syncfusion/add-digital-signatures-to-a-wpf-pdf-viewer-with-a-click-to-place-esign-workflow-3ome</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Learn to implement digital signatures inside the Syncfusion WPF PDF Viewer using programmatic techniques. It covers adding a custom eSign button, capturing click positions, generating a signature image, and applying a certificate-based signature. It enables a smooth, secure in-app signing experience even though the viewer does not support signature creation through its UI.&lt;/p&gt;

&lt;h2&gt;
  
  
  Digital signatures are no longer optional
&lt;/h2&gt;

&lt;p&gt;A digital signature is a cryptographic stamp applied to a document using a certificate containing a private key. It isn’t just about convenience; it’s about &lt;strong&gt;trust&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Digital signatures ensure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Document authenticity.&lt;/li&gt;
&lt;li&gt;Tamper protection.&lt;/li&gt;
&lt;li&gt; Verified signer identity.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For this reason, digital signatures are standard in legal, financial, and enterprise document workflows.&lt;/p&gt;

&lt;h2&gt;
  
  
  The smart workaround: In‑app digital signing in WPF PDF Viewer
&lt;/h2&gt;

&lt;p&gt;While Syncfusion &lt;a href="https://www.syncfusion.com/pdf-viewer-sdk/wpf-pdf-viewer" rel="noopener noreferrer"&gt;WPF PDF Viewer&lt;/a&gt; currently supports viewing digital signatures, it does not allow adding or modifying them directly through the UI.&lt;/p&gt;

&lt;p&gt;But by combining the Syncfusion WPF PDF Viewer and .NET PDF  Library, we can enable programmatic digital signing. We can customize the toolbar, capture user interactions, and embed a certificate-based signature with a dynamically generated image.&lt;/p&gt;

&lt;p&gt;Instead of relying on external tools or complex user flows, this solution enables &lt;strong&gt;secure, fully integrated digital signing,&lt;/strong&gt; right inside your WPF PDF Viewer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Requirements
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Set up the environment
&lt;/h3&gt;

&lt;p&gt;Install the following prerequisites:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://visualstudio.microsoft.com/downloads/" rel="noopener noreferrer"&gt;Visual Studio 2022&lt;/a&gt; or newer with the WPF workload enabled.&lt;/li&gt;
&lt;li&gt;The &lt;a href="https://www.nuget.org/packages/Syncfusion.PdfViewer.WPF" rel="noopener noreferrer"&gt;Sycfusion.PdfViewer.WPF&lt;/a&gt; NuGet package, which includes both the viewer control and the PDF processing library.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Certificate for signing
&lt;/h3&gt;

&lt;p&gt;We need a valid &lt;code&gt;.pfx&lt;/code&gt; certificate file that contains a private key. This certificate is used to securely sign the PDF and embed metadata such as the signer’s identity, location, and signing reason.&lt;/p&gt;

&lt;h2&gt;
  
  
  Add a digital signature using Syncfusion WPF PDF Viewer and .NET PDF Library
&lt;/h2&gt;

&lt;p&gt;This digital signing workflow is built around the following  four key steps:&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Add an eSign button to the toolbar
&lt;/h3&gt;

&lt;p&gt;When the WPF PDF Viewer loads, you can inject a custom eSign button into the existing toolbar.&lt;/p&gt;

&lt;p&gt;To keep the UI consistent, we will reuse the style and icon of an existing toolbar item, as shown in the following code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;PDFViewer_Loaded&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;object&lt;/span&gt; &lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;RoutedEventArgs&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;toolbar&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PDFViewer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Template&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FindName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"PART_Toolbar"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PDFViewer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;DocumentToolbar&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;stackPanel&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;toolbar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Template&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FindName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"PART_ToolbarStack"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;toolbar&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;StackPanel&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;defaultButton&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;)((&lt;/span&gt;&lt;span class="n"&gt;StackPanel&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;stackPanel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Children&lt;/span&gt;&lt;span class="p"&gt;[^&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="n"&gt;Children&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;eSignButton&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;GetButton&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;defaultButton&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;defaultButton&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;stackPanel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Children&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;eSignButton&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;GetButton&lt;/code&gt; method is responsible for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creating the new button,&lt;/li&gt;
&lt;li&gt;Applying the existing style, and&lt;/li&gt;
&lt;li&gt;Attaching the click event that activates the signing mode.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 2: Capture the exact spot where the user clicks
&lt;/h3&gt;

&lt;p&gt;Once the eSign button is clicked, a flag is set to indicate that the next mouse click should trigger signature placement. This will convert the mouse-click coordinates to page-relative positions using the WPF PDF Viewer’s built-in method. So, the signature lands exactly where the user clicked.&lt;/p&gt;

&lt;p&gt;This ensures:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pixel‑perfect placement.&lt;/li&gt;
&lt;li&gt;Support for multi‑page PDFs.&lt;/li&gt;
&lt;li&gt;A natural “click‑to‑sign” feel users already expect.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Refer to the following code example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;PDFViewer_PageClicked&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;object&lt;/span&gt; &lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PageClickedEventArgs&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;addSignature&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pageIndex&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PDFViewer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CurrentPageIndex&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pagePoint&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PDFViewer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ConvertClientPointToPagePoint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Position&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pageIndex&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
          &lt;span class="nf"&gt;ApplySignature&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pageIndex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pagePoint&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
          &lt;span class="n"&gt;addSignature&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Dynamically generate a signature image
&lt;/h3&gt;

&lt;p&gt;Instead of a generic stamp, this solution creates a meaningful visual signature. It:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Generates a runtime image block containing:

&lt;ul&gt;
&lt;li&gt;Signer name.&lt;/li&gt;
&lt;li&gt;Date and time.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Combines it with a handwritten‑style name image.&lt;/li&gt;

&lt;li&gt;Produces a polished &lt;strong&gt;eSign graphic&lt;/strong&gt; every time.&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;The visual result meets professional and regulatory requirements.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreateCurrentDataImage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;$"Digitally signed by John\nDate: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;yyyy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dd&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;nHH&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;mm&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;ss&lt;/span&gt; &lt;span class="n"&gt;zzz&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
     &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;bitmap&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Bitmap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
     &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;graphics&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Graphics&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromImage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bitmap&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
     &lt;span class="n"&gt;graphics&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FillRectangle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Brushes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;White&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
     &lt;span class="n"&gt;graphics&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;DrawString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Font&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Arial"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;9&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;Brushes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Black&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;RectangleF&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;180&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
     &lt;span class="n"&gt;bitmap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filePath&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"DigitalSignatureBlock.png"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ImageFormat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Png&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CombineSignatureAndDataImage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;nameImage&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filePath&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"John.png"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;signImage&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filePath&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"DigitalSignatureBlock.png"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;combinedImage&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Bitmap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nameImage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Width&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;signImage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nameImage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Height&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;signImage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Height&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
      &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Graphics&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromImage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;combinedImage&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;DrawImage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nameImage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;DrawImage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;signImage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nameImage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="n"&gt;combinedImage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filePath&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"ESign.png"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ImageFormat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Png&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4: Apply a certificate‑based digital signature
&lt;/h3&gt;

&lt;p&gt;Here’s where security comes in. Using the &lt;code&gt;.pfx&lt;/code&gt; certificate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A cryptographic digital signature is applied.&lt;/li&gt;
&lt;li&gt;Metadata is embedded (reason, location, contact information).&lt;/li&gt;
&lt;li&gt;The signature is rendered visually at the chosen location.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then, the PDF is saved and reloaded, now officially signed. All of this happens programmatically and securely.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;ApplySignature&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;pageIndex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Point&lt;/span&gt; &lt;span class="n"&gt;pagePoint&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PDFViewer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LoadedDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pages&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;pageIndex&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;PdfLoadedPage&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;cert&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;PdfCertificate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filePath&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"PDF.pfx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"password123"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;signature&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;PdfSignature&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PDFViewer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LoadedDocument&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cert&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Signature"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;image&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;PdfBitmap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filePath&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"ESign.png"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="n"&gt;signature&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Bounds&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;RectangleF&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="kt"&gt;float&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;pagePoint&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;float&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;pagePoint&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PhysicalDimension&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PhysicalDimension&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Height&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="n"&gt;signature&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ContactInfo&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"johndoe@owned.us"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="n"&gt;signature&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LocationInfo&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Honolulu, Hawaii"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="n"&gt;signature&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Reason&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"I am the author of this document."&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="n"&gt;signature&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Appearance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Normal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Graphics&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;DrawImage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;stream&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;MemoryStream&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="n"&gt;PDFViewer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LoadedDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Position&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="n"&gt;PDFViewer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This article was originally published at &lt;a href="https://www.syncfusion.com/blogs/post/add-in-app-digital-sign-wpf-pdf-viewer" rel="noopener noreferrer"&gt;Syncfusion.com.&lt;/a&gt;&lt;/p&gt;

</description>
      <category>pdf</category>
      <category>desktop</category>
      <category>digitalsignature</category>
      <category>documentprocessing</category>
    </item>
    <item>
      <title>Best LLM APIs in 2026: Comparing OpenAI, Claude, Gemini, Azure, Bedrock, Mistral &amp; DeepSeek</title>
      <dc:creator>Calvince Moth</dc:creator>
      <pubDate>Wed, 08 Apr 2026 12:56:03 +0000</pubDate>
      <link>https://dev.to/syncfusion/best-llm-apis-in-2026-comparing-openai-claude-gemini-azure-bedrock-mistral-deepseek-18d</link>
      <guid>https://dev.to/syncfusion/best-llm-apis-in-2026-comparing-openai-claude-gemini-azure-bedrock-mistral-deepseek-18d</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;: Choosing an LLM API in 2026 isn’t about “the best model”; it’s about the best fit for your workload. &lt;strong&gt;OpenAI&lt;/strong&gt; and &lt;strong&gt;Claude&lt;/strong&gt; lead in agentic workflows and developer speed, Gemini dominates multimodal long-context tasks, Azure OpenAI and AWS Bedrock excel in regulated enterprise environments, Mistral offers an EU-friendly open-weight path, and DeepSeek wins on ultra-low cost with OpenAI-compatible APIs.&lt;/p&gt;

&lt;p&gt;The LLM API market in 2026 is no longer the “wild west”, but it still changes fast enough that last year’s comparison posts age out quickly. Most major providers now ship new model families every few months.  &lt;strong&gt;1M-token context&lt;/strong&gt;  is common across flagships. And  &lt;strong&gt;agentic features&lt;/strong&gt;  (tool calling, computer use, multi-step workflows) are now expected, not “nice to have.”&lt;/p&gt;

&lt;p&gt;So what actually separates a good architectural choice from a painful one?&lt;/p&gt;

&lt;p&gt;Not marketing. The difference shows up in the boring-but-critical details: latency under load, pricing at scale, SDK quality, compliance posture, rate limits, and deprecation timelines.&lt;/p&gt;

&lt;p&gt;This guide compares the  &lt;strong&gt;top 7 LLM APIs of 2026&lt;/strong&gt;  with production reality in mind.&lt;/p&gt;

&lt;h2&gt;
  
  
  The real developer pain (what hits in production)
&lt;/h2&gt;

&lt;p&gt;Teams rarely fail because they picked the “wrong” model. They fail because the platform’s operational details don’t match their workload.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Common pain points&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Onboarding friction:&lt;/strong&gt; SDK maturity and example depth decide whether “Hello, world” takes 10 minutes or half a day.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Architecture trade‑offs:&lt;/strong&gt; Do you rely on &lt;code&gt;1M‑token prompts&lt;/code&gt; or build a slim RAG layer? Your choice impacts latency, token spend, and maintainability.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Latency-sensitive apps:&lt;/strong&gt; Streaming &lt;code&gt;TTFT&lt;/code&gt; matters more than raw &lt;code&gt;TPS&lt;/code&gt;; caching helps TTFT, not generation speed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost unpredictability:&lt;/strong&gt; Learn the batch API and prompt caching knobs or pay &lt;code&gt;40–60%&lt;/code&gt; more than you need.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vendor lock-in:&lt;/strong&gt; Proprietary caching keys, computer‑use runtimes, quota models can become hard dependencies; abstract early.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Production reliability:&lt;/strong&gt; Watch rate limits, region availability, and model deprecation windows; build for churn.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What’s changed in 2026
&lt;/h2&gt;

&lt;p&gt;The AI API landscape shifted fast this year. Three big changes reshaped developer choices:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;1M+ context windows became normal&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
All major vendors now support &lt;code&gt;~1M tokens&lt;/code&gt;. Long-context workflows (codebases, legal docs, video transcripts) are finally mainstream.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Agentic capabilities matured&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Computer use, multi-step tool calls, and structured reasoning are no longer experimental. Some providers are still ahead here (notably Claude and OpenAI), while others are still catching up.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cost spread widened dramatically&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
DeepSeek disrupted pricing at the bottom end. Azure and Bedrock increased their enterprise tooling. OpenAI and Anthropic improved caching and batch options, making large contexts cheaper in practice.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Net result:&lt;/strong&gt; In 2026, teams choose based on &lt;strong&gt;workflow + constraints&lt;/strong&gt;, not just raw model quality.&lt;/p&gt;

&lt;p&gt;This article was originally published at &lt;a href="https://www.syncfusion.com/blogs/post/top-llm-api-comparison-2026" rel="noopener noreferrer"&gt;Syncfusion.com.&lt;/a&gt;&lt;/p&gt;

</description>
      <category>llmapi</category>
      <category>aiapis</category>
      <category>enterpriseai</category>
      <category>generativeaiplatform</category>
    </item>
    <item>
      <title>How to Integrate React Gantt Chart in Framer</title>
      <dc:creator>Calvince Moth</dc:creator>
      <pubDate>Wed, 08 Apr 2026 11:30:12 +0000</pubDate>
      <link>https://dev.to/syncfusion/how-to-integrate-react-gantt-chart-in-framer-3c0m</link>
      <guid>https://dev.to/syncfusion/how-to-integrate-react-gantt-chart-in-framer-3c0m</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Tired of inefficient coding cycles in project management tools? Integrating a React Gantt Chart into Framer streamlines setup, delivers structured files, and enables task-driven execution, all directly on the canvas. With Framer’s developer mode and Gantt integration, you achieve an efficient workflow that keeps project timelines precise. The result is fewer errors, faster previews, neater layouts, and scalable visualizations for your team.&lt;/p&gt;

&lt;p&gt;The Syncfusion&lt;sup&gt;®&lt;/sup&gt; &lt;a href="https://www.syncfusion.com/react-ui-components/react-gantt-chart" rel="noopener noreferrer"&gt;React Gantt Chart&lt;/a&gt; is a robust tool for project planning and tracking. It provides an interactive timeline to manage tasks, dependencies, and resources with built-in editing and drag-and-drop. Using it in Framer’s design and prototyping platform allows developers and designers to build interactive, data-driven project management UIs.&lt;/p&gt;

&lt;p&gt;This blog walks through a step-by-step approach to integrating the Syncfusion React Gantt Chart into a Framer project, including a practical, working code example to help you get started quickly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why integrate Syncfusion React Gantt Chart with Framer?
&lt;/h2&gt;

&lt;p&gt;Framer’s developer mode supports React-based components, making it an ideal platform for embedding Syncfusion’s feature-rich Gantt Chart. This integration is perfect for prototyping complex project timelines interactively, bridging the gap between design and development.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key benefits:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Dynamic visualizations&lt;/strong&gt;: Display tasks, dependencies, and milestones with Syncfusion’s customizable Gantt Chart.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Interactive prototyping&lt;/strong&gt;: Leverage Framer’s design environment to create user-friendly interfaces.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Seamless integration&lt;/strong&gt;: Combine Syncfusion’s robust functionality with Framer’s flexible canvas.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before starting, ensure you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A valid &lt;a href="https://ej2.syncfusion.com/react/documentation/licensing/license-key-generation" rel="noopener noreferrer"&gt;Syncfusion license key&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.framer.com/downloads/" rel="noopener noreferrer"&gt;Framer desktop application&lt;/a&gt; installed.&lt;/li&gt;
&lt;li&gt;Basic knowledge of React, TypeScript, and Framer’s developer mode.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Integrating Framer and Syncfusion React Gantt Chart
&lt;/h2&gt;

&lt;p&gt;The first step in integrating the Syncfusion &lt;a href="https://ej2.syncfusion.com/react/documentation/gantt/getting-started" rel="noopener noreferrer"&gt;React Gantt Chart&lt;/a&gt; into &lt;a href="https://www.framer.com/developers/" rel="noopener noreferrer"&gt;Framer&lt;/a&gt; is to set up your development environment.&lt;/p&gt;

&lt;p&gt;Framer is built for design and prototyping, while the React Gantt Chart delivers advanced project management features. Integrating both requires a few setup steps for a smooth developer workflow.&lt;/p&gt;

&lt;p&gt;This article was originally published at &lt;a href="https://www.syncfusion.com/blogs/post/integrate-react-gantt-chart-in-framer" rel="noopener noreferrer"&gt;Syncfusion.com.&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>datavisualization</category>
      <category>developerproductivit</category>
      <category>framertutorials</category>
    </item>
    <item>
      <title>How to Implement Cut, Copy, and Paste Support in React Spreadsheet</title>
      <dc:creator>Calvince Moth</dc:creator>
      <pubDate>Tue, 07 Apr 2026 11:46:33 +0000</pubDate>
      <link>https://dev.to/syncfusion/how-to-implement-cut-copy-and-paste-support-in-react-spreadsheet-2aoj</link>
      <guid>https://dev.to/syncfusion/how-to-implement-cut-copy-and-paste-support-in-react-spreadsheet-2aoj</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Modern spreadsheets aren’t complete without intuitive clipboard support. This guide shows how to implement and customize cut, copy, and paste operations in a React Spreadsheet, whether through the UI or APIs. You’ll also learn how to handle data from external sources and restrict specific paste actions to preserve data integrity.&lt;/p&gt;

&lt;p&gt;Clipboard support is one of those features users only notice when it doesn’t work. If you’re building an app with a spreadsheet-like UI, people expect Excel-style cut/copy/paste, keyboard shortcuts, and sane behavior when they paste data from outside your app.&lt;/p&gt;

&lt;p&gt;In this post, we’ll walk through how to handle clipboard operations in the &lt;a href="https://www.syncfusion.com/spreadsheet-editor-sdk/react-spreadsheet-editor" rel="noopener noreferrer"&gt;Syncfusion &lt;strong&gt;&lt;sup&gt;®&lt;/sup&gt;&lt;/strong&gt; React Spreadsheet&lt;/a&gt;, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cut, copy, and paste.&lt;/li&gt;
&lt;li&gt;Paste options (All / Values / Formats).&lt;/li&gt;
&lt;li&gt;Pasting from external sources (Excel, Google Sheets, etc.).&lt;/li&gt;
&lt;li&gt;Preventing paste entirely.&lt;/li&gt;
&lt;li&gt;Allowing external paste but forcing  &lt;strong&gt;values-only&lt;/strong&gt; to keep your sheet clean.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why clipboard handling matters (in real apps)
&lt;/h2&gt;

&lt;p&gt;Developers usually run into clipboard issues in a few common scenarios:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Data-entry screens:&lt;/strong&gt;  Users paste formatted tables and blow up your styling, column formats, or validations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Template-based sheets:&lt;/strong&gt;  You want to protect formulas and layout, but still let users paste values.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Controlled environments:&lt;/strong&gt;  You may need to disable cut/paste for compliance or to avoid accidental edits.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Interop with Excel:&lt;/strong&gt;  Users expect copy/paste from Excel to “just work,” including number formats.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is where built-in clipboard support helps, but the key is knowing how to control it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Clipboard operations in Syncfusion React Spreadsheet
&lt;/h2&gt;

&lt;p&gt;When you’re working with Spreadsheets, cut, copy, and paste aren’t just basic actions; they’re the backbone of smooth data handling. The component offers a robust set of options for managing data:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cut, copy, and paste&lt;/strong&gt;: Perform standard clipboard operations on cells, ranges, and formulas.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;External clipboard support&lt;/strong&gt;: Copy data from external sources such as Excel or other applications and paste it into the Spreadsheet.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Paste options&lt;/strong&gt;: Choose whether to paste entire cells, values only, or formats only for more control over data handling.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rich content handling&lt;/strong&gt;: Copy and paste charts, images, and hyperlinks within the Spreadsheet.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keyboard shortcuts&lt;/strong&gt;: Use familiar shortcuts such as &lt;code&gt;Ctrl+C&lt;/code&gt;, &lt;code&gt;Ctrl+X&lt;/code&gt;, and &lt;code&gt;Ctrl+V&lt;/code&gt; for quick clipboard actions.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Enable clipboard operations
&lt;/h2&gt;

&lt;p&gt;The Syncfusion React Spreadsheet includes built-in clipboard functionality, making these operations easy to use. If you need to enable/disable them globally, use the &lt;a href="https://ej2.syncfusion.com/react/documentation/api/spreadsheet/index-default#enableclipboard" rel="noopener noreferrer"&gt;enableClipboard&lt;/a&gt; property (enabled by default).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;SpreadsheetComponent&lt;/span&gt; &lt;span class="na"&gt;enableClipboard=&lt;/span&gt;&lt;span class="s"&gt;{true}&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Cut like a pro
&lt;/h2&gt;

&lt;p&gt;Need to move data around in your Spreadsheet? That’s where the Cut operation comes in. It allows you to move data without creating duplicates. When you cut cells, rows, or columns, the content is stored in the clipboard but remains in place until you paste it. The original data is removed only after the paste action is completed.&lt;/p&gt;

&lt;p&gt;The Syncfusion React Spreadsheet makes moving data straightforward. Here are the different ways to perform a cut:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Ribbon shortcut:&lt;/strong&gt; Click the &lt;strong&gt;Cut&lt;/strong&gt; button in the &lt;strong&gt;HOME&lt;/strong&gt; tab of the Ribbon.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F04%2FCut-data-via-the-Home-Tab.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F04%2FCut-data-via-the-Home-Tab.png" alt="&amp;lt;alt-text&amp;gt;" width="800" height="43"&gt;&lt;/a&gt;&lt;br&gt;Cut data via the Home Tab
  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Context Menu:&lt;/strong&gt; Right-click the target cell and select &lt;strong&gt;Cut&lt;/strong&gt; option from the context menu.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F03%2FCut-data-via-context-menu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F03%2FCut-data-via-context-menu.png" alt="&amp;lt;alt-text&amp;gt;" width="198" height="469"&gt;&lt;/a&gt;&lt;br&gt;Cut data via context menu
  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Keyboard shortcut:&lt;/strong&gt; Press &lt;strong&gt;Ctrl + X&lt;/strong&gt; (Windows) or &lt;strong&gt;Command + X&lt;/strong&gt; on Mac for the quickest way to cut data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API support:&lt;/strong&gt; Use the &lt;a href="https://ej2.syncfusion.com/react/documentation/api/spreadsheet/index-default#cut" rel="noopener noreferrer"&gt;cut()&lt;/a&gt; method to trigger the cut action programmatically. When called without parameters, it cuts data based on the current selection. When a range address is provided, it cuts data from the specified range.
Try this in your code:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// cuts the currently selected range&lt;/span&gt;
&lt;span class="nx"&gt;spreadsheet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cut&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// cuts the given address range&lt;/span&gt;
&lt;span class="nx"&gt;spreadsheet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cut&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;A2:C5&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Copy made simple: Duplicate data in the Syncfusion React Spreadsheet
&lt;/h2&gt;

&lt;p&gt;Sometimes you don’t need to move data; just create an extra copy. The Copy operation lets you duplicate selected cells, rows, or columns and store them in the clipboard, ready to be pasted anywhere in the Spreadsheet.&lt;/p&gt;

&lt;p&gt;The Syncfusion React Spreadsheet offers multiple ways to copy data, allowing you to choose the most convenient approach:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Ribbon shortcut:&lt;/strong&gt; Click the &lt;strong&gt;Copy&lt;/strong&gt; button in the &lt;strong&gt;HOME&lt;/strong&gt; tab.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F03%2FCopy-data-via-Ribbon-Tab.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F03%2FCopy-data-via-Ribbon-Tab.png" alt="&amp;lt;alt-text&amp;gt;" width="800" height="43"&gt;&lt;/a&gt;&lt;br&gt;Copy data via Ribbon Tab
  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Context Menu:&lt;/strong&gt; Right-click the target cell or range and select &lt;strong&gt;Copy&lt;/strong&gt; from the context menu.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F03%2FCopy-data-via-context-menu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F03%2FCopy-data-via-context-menu.png" alt="&amp;lt;alt-text&amp;gt;" width="198" height="469"&gt;&lt;/a&gt;&lt;br&gt;Copy data via context menu
  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Keyboard shortcut:&lt;/strong&gt; Press &lt;strong&gt;Ctrl + C&lt;/strong&gt; (Windows) or &lt;strong&gt;Command + C&lt;/strong&gt; (Mac) for quick copying.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API support:&lt;/strong&gt; Use the &lt;a href="https://ej2.syncfusion.com/react/documentation/api/spreadsheet/index-default#cut" rel="noopener noreferrer"&gt;cut()&lt;/a&gt; method when copying through code. When called without parameters, it copies data based on the current selection. When a range address is provided, it copies data from the specified range.
Code snippet:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// copy the currently selected range&lt;/span&gt;
&lt;span class="nx"&gt;spreadsheet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;copy&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// copy data from the specified range&lt;/span&gt;
&lt;span class="nx"&gt;spreadsheet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;copy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;A2:C5&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Paste in React Spreadsheet
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;Paste&lt;/strong&gt; operation allows you to insert clipboard content into cells, rows, or columns quickly and accurately. It enables you to move copied or cut data into the Spreadsheet with full control over what gets pasted.&lt;/p&gt;

&lt;p&gt;Paste options available:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Paste All&lt;/strong&gt;: Pastes both values and their original formatting.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Paste Values&lt;/strong&gt;: Pastes only the values, without any formatting.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Paste Formats&lt;/strong&gt;: Applies formatting such as font styles, colors, background colors, and number formats (date, currency, etc.) without modifying existing values.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F03%2FPaste-Special-via-Ribbon.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F03%2FPaste-Special-via-Ribbon.png" alt="&amp;lt;alt-text&amp;gt;" width="800" height="166"&gt;&lt;/a&gt;&lt;br&gt;Paste Special via Ribbon
  &lt;/p&gt;

&lt;h3&gt;
  
  
  Paste from anywhere: External clipboard made easy
&lt;/h3&gt;

&lt;p&gt;The React Spreadsheet supports pasting data copied from external applications such as Excel. Supported content includes values, number formats (date, currency, percentage), text formatting (bold, italic, font color), and basic cell formatting like background color and borders. This ensures imported data retains its readability and structure.&lt;/p&gt;

&lt;p&gt;Ways to paste data in Syncfusion React Spreadsheet:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Ribbon shortcut&lt;/strong&gt;: Click the &lt;strong&gt;Paste&lt;/strong&gt; button in the &lt;strong&gt;HOME&lt;/strong&gt; tab as shown below.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F03%2FPaste-data-via-Ribbon.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F03%2FPaste-data-via-Ribbon.png" alt="&amp;lt;alt-text&amp;gt;" width="800" height="40"&gt;&lt;/a&gt;&lt;br&gt;Paste data via Ribbon
  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Context Menu&lt;/strong&gt;: Right-click a cell and choose the &lt;strong&gt;Paste&lt;/strong&gt; or &lt;strong&gt;Paste Special&lt;/strong&gt; option from the context menu.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F03%2FPaste-data-via-context-menu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F03%2FPaste-data-via-context-menu.png" alt="&amp;lt;alt-text&amp;gt;" width="198" height="469"&gt;&lt;/a&gt;&lt;br&gt;Paste data via context menu
  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Keyboard shortcut&lt;/strong&gt;: Press &lt;code&gt;Ctrl + V&lt;/code&gt; (Windows) or &lt;code&gt;Command + V&lt;/code&gt; (Mac) for the quickest way to paste.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API support&lt;/strong&gt;: Use the &lt;a href="https://ej2.syncfusion.com/react/documentation/api/spreadsheet/index-default#paste" rel="noopener noreferrer"&gt;paste()&lt;/a&gt; method to control paste behavior programmatically. Calling paste() without parameters pastes content into the current selection. Providing a range address and an optional &lt;a href="https://ej2.syncfusion.com/react/documentation/api/spreadsheet/pastespecialtype" rel="noopener noreferrer"&gt;PasteSpecialType&lt;/a&gt; enumeration, lets you specify both the target location and paste behavior.
Here’s how you can do it in code:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Paste the selected cell.&lt;/span&gt;
&lt;span class="nx"&gt;spreadsheet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;paste&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// Paste all the clipboard content to the specified range.&lt;/span&gt;
&lt;span class="nx"&gt;spreadsheet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;paste&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;B2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;All&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Paste only the values to the specified range.&lt;/span&gt;
&lt;span class="nx"&gt;spreadsheet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;paste&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;B3&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Values&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Apply only the formats to the specified range.&lt;/span&gt;
&lt;span class="nx"&gt;spreadsheet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;paste&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;B4&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Formats&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code example above, the &lt;a href="https://ej2.syncfusion.com/react/documentation/api/spreadsheet/index-default#paste" rel="noopener noreferrer"&gt;paste()&lt;/a&gt; method gives you full control over where and how clipboard data is inserted, making it easy to handle simple and advanced paste scenarios.&lt;/p&gt;

&lt;p&gt;This article was originally published at &lt;a href="https://www.syncfusion.com/blogs/post/clipboard-operations-in-react-spreadsheet" rel="noopener noreferrer"&gt;Syncfusion.com.&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>excellikespreadsheet</category>
      <category>reactspreadsheet</category>
      <category>spreadsheet</category>
    </item>
    <item>
      <title>Tired of Multiple Viewers? Build a Universal Document Viewer in .NET MAUI</title>
      <dc:creator>Calvince Moth</dc:creator>
      <pubDate>Tue, 07 Apr 2026 11:36:58 +0000</pubDate>
      <link>https://dev.to/syncfusion/tired-of-multiple-viewers-build-a-universal-document-viewer-in-net-maui-4ah5</link>
      <guid>https://dev.to/syncfusion/tired-of-multiple-viewers-build-a-universal-document-viewer-in-net-maui-4ah5</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Multi‑format document handling in apps doesn’t need separate viewers. By converting Word, Excel, PowerPoint, Images, and XPS into PDF, the .NET MAUI PDF Viewer becomes a universal document hub. Developers get one streamlined interface for previewing, annotating, and collaborating across formats. The result: simpler workflows, consistent user experience, reduced complexity, and scalable cross‑platform document management.&lt;/p&gt;

&lt;h2&gt;
  
  
  The big idea: PDF as the universal document viewer layer
&lt;/h2&gt;

&lt;p&gt;Modern cross-platform apps rarely deal with “ &lt;strong&gt;just PDFs&lt;/strong&gt;.” Users open Word docs, Excel sheets, PowerPoint decks, images, and even XPS files, often inside the same workflow. The problem: building and maintaining a separate viewer per format is costly, inconsistent across platforms, and hard to scale.&lt;/p&gt;

&lt;p&gt;To create a smoother workflow, adopt a simpler approach: standardize PDF as the universal document viewer format. By converting incoming files to PDF, you enable seamless rendering through a single PDF Viewer component.&lt;/p&gt;

&lt;p&gt;With this strategy in mind, this blog will guide you through setting up a unified document viewing workflow for your .NET MAUI apps.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why convert everything to PDF?
&lt;/h2&gt;

&lt;p&gt;PDF is a stable, layout-preserving format that works well for preview and review scenarios:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Consistent UI rendering across mobile and desktop apps.&lt;/li&gt;
&lt;li&gt;One viewer instead of multiple format-specific viewers.&lt;/li&gt;
&lt;li&gt;Safe review workflows (annotations instead of editing the original).&lt;/li&gt;
&lt;li&gt;Easier enterprise controls (stream-based loading, reduced file persistence).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The star of the show: Syncfusion .NET MAUI PDF Viewer
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://www.syncfusion.com/maui-controls/maui-pdf-viewer" rel="noopener noreferrer"&gt;Syncfusion&lt;sup&gt;®&lt;/sup&gt; .NET MAUI PDF Viewer&lt;/a&gt; natively supports PDF files and offers a rich interaction model. When combined with Syncfusion &lt;a href="https://www.syncfusion.com/document-processing-libraries" rel="noopener noreferrer"&gt;Document Processing Libraries&lt;/a&gt;, it becomes a complete, universal document viewing engine.&lt;/p&gt;

&lt;p&gt;Once all documents are converted to PDF, the &lt;a href="https://www.nuget.org/packages/Syncfusion.Maui.PdfViewer/" rel="noopener noreferrer"&gt;.NET MAUI PDF Viewer&lt;/a&gt; presents a single, consistent UI across all formats.&lt;/p&gt;

&lt;h3&gt;
  
  
  What you can preview: Supported document types
&lt;/h3&gt;

&lt;p&gt;The &lt;a href="https://help.syncfusion.com/document-processing/pdf/pdf-viewer/maui/getting-started" rel="noopener noreferrer"&gt;Syncfusion .NET MAUI PDF Viewer&lt;/a&gt; supports converting and previewing the following five commonly used file types into PDF format:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Word documents&lt;/li&gt;
&lt;li&gt;Excel workbooks&lt;/li&gt;
&lt;li&gt;PowerPoint presentations&lt;/li&gt;
&lt;li&gt;Images&lt;/li&gt;
&lt;li&gt;XPS files&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Behind the scenes: Document conversion engine stack
&lt;/h2&gt;

&lt;p&gt;To convert various file formats into PDF, Syncfusion offers a range of document processing libraries. Depending on the file type and your specific requirements, one or more of these libraries can be used:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Word to PDF:&lt;/strong&gt; &lt;a href="https://www.nuget.org/packages/Syncfusion.DocIORenderer.NET" rel="noopener noreferrer"&gt;Syncfusion.DocIORenderer.NET&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Excel to PDF:&lt;/strong&gt; &lt;a href="https://www.nuget.org/packages/Syncfusion.XlsIORenderer.NET" rel="noopener noreferrer"&gt;Syncfusion.XlsIORenderer.Net&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PowerPoint to PDF:&lt;/strong&gt; &lt;a href="https://www.nuget.org/packages/Syncfusion.PresentationRenderer.NET" rel="noopener noreferrer"&gt;Syncfusion.PresentationRenderer.NET&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Images to PDF:&lt;/strong&gt; &lt;a href="https://www.nuget.org/packages/Syncfusion.Pdf.Imaging.NET" rel="noopener noreferrer"&gt;Syncfusion.Pdf.Imaging.NET&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;XPS to PDF:&lt;/strong&gt; &lt;a href="https://www.nuget.org/packages/Syncfusion.XpsToPdfConverter.NET" rel="noopener noreferrer"&gt;Syncfusion.XpsToPdfConverter.NET&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each library handles format‑specific conversion, producing a &lt;code&gt;PdfDocument&lt;/code&gt; object that can be passed to the viewer. Using this approach maintains high fidelity and preserves layouts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Essential setup and configuration
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;First, we need to establish the foundation by creating a new &lt;a href="https://learn.microsoft.com/en-us/dotnet/maui/get-started/first-app?view=net-maui-10.0&amp;amp;tabs=vswin&amp;amp;pivots=devices-android" rel="noopener noreferrer"&gt;.NET MAUI app&lt;/a&gt;. Then, install the required packages for the .NET MAUI PDF Viewer and document processing libraries.
Here’s the code you need:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;PackageReference&lt;/span&gt; &lt;span class="na"&gt;Include=&lt;/span&gt;&lt;span class="s"&gt;"Syncfusion.DocIORenderer.NET"&lt;/span&gt; &lt;span class="na"&gt;Version=&lt;/span&gt;&lt;span class="s"&gt;"*"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;PackageReference&lt;/span&gt; &lt;span class="na"&gt;Include=&lt;/span&gt;&lt;span class="s"&gt;"Syncfusion.Maui.PdfViewer"&lt;/span&gt; &lt;span class="na"&gt;Version=&lt;/span&gt;&lt;span class="s"&gt;"*"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;PackageReference&lt;/span&gt; &lt;span class="na"&gt;Include=&lt;/span&gt;&lt;span class="s"&gt;"Syncfusion.Maui.TabView"&lt;/span&gt; &lt;span class="na"&gt;Version=&lt;/span&gt;&lt;span class="s"&gt;"*"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;PackageReference&lt;/span&gt; &lt;span class="na"&gt;Include=&lt;/span&gt;&lt;span class="s"&gt;"Syncfusion.Pdf.Imaging.NET"&lt;/span&gt; &lt;span class="na"&gt;Version=&lt;/span&gt;&lt;span class="s"&gt;"*"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;PackageReference&lt;/span&gt; &lt;span class="na"&gt;Include=&lt;/span&gt;&lt;span class="s"&gt;"Syncfusion.Presentation.NET"&lt;/span&gt; &lt;span class="na"&gt;Version=&lt;/span&gt;&lt;span class="s"&gt;"*"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;PackageReference&lt;/span&gt; &lt;span class="na"&gt;Include=&lt;/span&gt;&lt;span class="s"&gt;"Syncfusion.PresentationRenderer.NET"&lt;/span&gt; &lt;span class="na"&gt;Version=&lt;/span&gt;&lt;span class="s"&gt;"*"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

\&lt;span class="nt"&gt;&amp;lt;PackageReference&lt;/span&gt; &lt;span class="na"&gt;Include=&lt;/span&gt;&lt;span class="s"&gt;"Syncfusion.XlsIORenderer.NET"&lt;/span&gt; &lt;span class="na"&gt;Version=&lt;/span&gt;&lt;span class="s"&gt;"*"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;8
&lt;span class="nt"&gt;&amp;lt;PackageReference&lt;/span&gt; &lt;span class="na"&gt;Include=&lt;/span&gt;&lt;span class="s"&gt;"Syncfusion.XpsToPdfConverter.NET"&lt;/span&gt; &lt;span class="na"&gt;Version=&lt;/span&gt;&lt;span class="s"&gt;"*"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Next, configure the handlers in the &lt;code&gt;MauiProgram.cs&lt;/code&gt; file as shown in the code below:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Syncfusion.Maui.Core.Hosting&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;MauiApp&lt;/span&gt; &lt;span class="nf"&gt;CreateMauiApp&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MauiApp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateBuilder&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;builder&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UseMauiApp&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;App&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;()&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ConfigureSyncfusionCore&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Build&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Building a universal document viewer in .NET MAUI
&lt;/h2&gt;

&lt;p&gt;Let’s see the steps to build a seamless universal document viewing experience using the Syncfusion .NET MAUI PDF Viewer:&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Handle format-specific PDF conversions
&lt;/h3&gt;

&lt;p&gt;Once the required Syncfusion libraries are configured, implement the logic to convert each supported file type into a PDF.&lt;/p&gt;

&lt;p&gt;Below is a breakdown of the conversion logic for each supported format:&lt;/p&gt;

&lt;h4&gt;
  
  
  Word to PDF
&lt;/h4&gt;

&lt;p&gt;To convert a Word document, use the &lt;a href="https://help.syncfusion.com/cr/maui/Syncfusion.DocIORenderer.DocIORenderer.html#Syncfusion_DocIORenderer_DocIORenderer_ConvertToPDF_Syncfusion_DocIO_DLS_WordDocument_" rel="noopener noreferrer"&gt;DocIORenderer.ConvertToPDF(WordDocument)&lt;/a&gt; method, which converts a loaded &lt;a href="https://help.syncfusion.com/cr/maui/Syncfusion.DocIO.DLS.WordDocument.html" rel="noopener noreferrer"&gt;WordDocument&lt;/a&gt; into a &lt;a href="https://help.syncfusion.com/cr/maui/Syncfusion.Pdf.PdfDocument.html" rel="noopener noreferrer"&gt;PdfDocument&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Refer to the example below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Loading an existing Word document&lt;/span&gt;
&lt;span class="n"&gt;Assembly&lt;/span&gt; &lt;span class="n"&gt;assembly&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;App&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;GetTypeInfo&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;Assembly&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;WordDocument&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;WordDocument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;assembly&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetManifestResourceStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"SampleName.Assets.InputDocument.docx"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;FormatType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Docx&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Convert to PDF using DocIO's rendering engine&lt;/span&gt;
    &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DocIORenderer&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;DocIORenderer&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;PdfDocument&lt;/span&gt; &lt;span class="n"&gt;pdfDocument&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ConvertToPDF&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// Proceed to save as stream&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; You can check out more options and examples in the &lt;a href="https://help.syncfusion.com/document-processing/word/conversions/word-to-pdf/net/convert-word-document-to-pdf-in-maui" rel="noopener noreferrer"&gt;Word to PDF conversion guide&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Excel to PDF
&lt;/h4&gt;

&lt;p&gt;Excel workbooks can be converted using the &lt;a href="https://help.syncfusion.com/cr/maui/Syncfusion.XlsIORenderer.XlsIORenderer.html#Syncfusion_XlsIORenderer_XlsIORenderer_ConvertToPDF_Syncfusion_XlsIO_IWorkbook_" rel="noopener noreferrer"&gt;XlsIORenderer.ConvertToPDF(IWorkbook)&lt;/a&gt; method, which converts an &lt;a href="https://help.syncfusion.com/cr/maui/Syncfusion.XlsIO.IWorkbook.html" rel="noopener noreferrer"&gt;IWorkbook&lt;/a&gt; (Excel document) into a &lt;a href="https://help.syncfusion.com/cr/maui/Syncfusion.Pdf.PdfDocument.html" rel="noopener noreferrer"&gt;PdfDocument&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here’s the code example for quick conversion:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Initialize Excel engine and open workbook&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ExcelEngine&lt;/span&gt; &lt;span class="n"&gt;excelEngine&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ExcelEngine&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;IApplication&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;excelEngine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Excel&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;IWorkbook&lt;/span&gt; &lt;span class="n"&gt;workbook&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Workbooks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;assembly&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetManifestResourceStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"SampleName.Assets.InputDocument.xlsx"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

    &lt;span class="c1"&gt;// Convert workbook to PDF&lt;/span&gt;
    &lt;span class="n"&gt;XlsIORenderer&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;XlsIORenderer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;PdfDocument&lt;/span&gt; &lt;span class="n"&gt;pdfDocument&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ConvertToPDF&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;workbook&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Proceed to save as stream&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; You can check out more options and examples in the &lt;a href="https://helpstaging.syncfusion.com/document-processing/excel/conversions/excel-to-pdf/net/convert-excel-to-pdf-in-maui" rel="noopener noreferrer"&gt;Excel to PDF conversion guide&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  PowerPoint to PDF
&lt;/h4&gt;

&lt;p&gt;For PowerPoint presentations, the &lt;a href="https://help.syncfusion.com/cr/maui/Syncfusion.PresentationRenderer.PresentationToPdfConverter.html#Syncfusion_PresentationRenderer_PresentationToPdfConverter_Convert_Syncfusion_Presentation_IPresentation_" rel="noopener noreferrer"&gt;PresentationToPdfConverter.Convert(IPresentation)&lt;/a&gt; method handles the conversion of an &lt;a href="https://help.syncfusion.com/cr/maui/Syncfusion.Presentation.IPresentation.html" rel="noopener noreferrer"&gt;IPresentation&lt;/a&gt; (PowerPoint presentation) object into a  &lt;a href="https://help.syncfusion.com/cr/maui/Syncfusion.Pdf.PdfDocument.html" rel="noopener noreferrer"&gt;PdfDocument&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Please refer to the complete code block:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Open PowerPoint presentation&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IPresentation&lt;/span&gt; &lt;span class="n"&gt;presentation&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Presentation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;assembly&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetManifestResourceStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"SampleName.Assets.InputDocument.pptx"&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Convert slides to PDF pages&lt;/span&gt;
    &lt;span class="n"&gt;PdfDocument&lt;/span&gt; &lt;span class="n"&gt;pdfDocument&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PresentationToPdfConverter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Convert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;presentation&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// Proceed to save as stream&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; You can check out more options and examples in the &lt;a href="https://help.syncfusion.com/document-processing/powerpoint/conversions/powerpoint-to-pdf/net/convert-powerpoint-to-pdf-in-maui" rel="noopener noreferrer"&gt;PowerPoint to PDF conversion documentation.&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Image to PDF
&lt;/h4&gt;

&lt;p&gt;For image conversion, the &lt;a href="https://help.syncfusion.com/cr/maui/Syncfusion.Pdf.Graphics.PdfGraphics.html#Syncfusion_Pdf_Graphics_PdfGraphics_DrawImage_Syncfusion_Pdf_Graphics_PdfImage_System_Single_System_Single_" rel="noopener noreferrer"&gt;PdfGraphics.DrawImage()&lt;/a&gt; method facilitates the conversion of images to PDF by drawing a &lt;a href="https://help.syncfusion.com/cr/maui/Syncfusion.Pdf.Graphics.PdfBitmap.html" rel="noopener noreferrer"&gt;PdfBitmap&lt;/a&gt; onto a PDF page. You can load images from various sources using the &lt;code&gt;PdfBitmap&lt;/code&gt; class.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Create a new PDF and add a page&lt;/span&gt;
&lt;span class="n"&gt;PdfDocument&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;PdfDocument&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Add a page to the document&lt;/span&gt;
&lt;span class="n"&gt;PdfPage&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;PdfGraphics&lt;/span&gt; &lt;span class="n"&gt;graphics&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Graphics&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Load the image from the disk&lt;/span&gt;
&lt;span class="n"&gt;FileStream&lt;/span&gt; &lt;span class="n"&gt;imageStream&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;FileStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Autumn Leaves.jpg"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;FileMode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Open&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;FileAccess&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Read&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;PdfBitmap&lt;/span&gt; &lt;span class="n"&gt;image&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;PdfBitmap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;imageStream&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Draw the image&lt;/span&gt;
&lt;span class="n"&gt;graphics&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;DrawImage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; For more details, refer to the &lt;a href="https://help.syncfusion.com/document-processing/pdf/pdf-library/net/converting-images-to-pdf" rel="noopener noreferrer"&gt;Image to PDF Conversion guide&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  XPS to PDF
&lt;/h4&gt;

&lt;p&gt;XPS documents can be converted using the &lt;a href="https://help.syncfusion.com/cr/document-processing/Syncfusion.XPS.XPSToPdfConverter.html#Syncfusion_XPS_XPSToPdfConverter_Convert_System_IO_Stream_" rel="noopener noreferrer"&gt;XPSToPdfConverter.Convert(Stream)&lt;/a&gt; method, which converts an XPS file stream into a &lt;a href="https://help.syncfusion.com/cr/maui/Syncfusion.Pdf.PdfDocument.html" rel="noopener noreferrer"&gt;PdfDocument&lt;/a&gt;, preserving the document layout and the visual appearance of each page.&lt;/p&gt;

&lt;p&gt;Code snippet to achieve this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Load XPS file and convert to PDF&lt;/span&gt;
&lt;span class="n"&gt;XPSToPdfConverter&lt;/span&gt; &lt;span class="n"&gt;converter&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;XPSToPdfConverter&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;FileStream&lt;/span&gt; &lt;span class="n"&gt;xpsStream&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;FileStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"sample.xps"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;FileMode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Open&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;FileAccess&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReadWrite&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;PdfDocument&lt;/span&gt; &lt;span class="n"&gt;pdfDocument&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;converter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Convert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;xpsStream&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// Proceed to save as stream&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; For detailed information, refer to the &lt;a href="https://help.syncfusion.com/document-processing/pdf/pdf-library/net/converting-xps-to-pdf" rel="noopener noreferrer"&gt;XPS to PDF conversion documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This article was originally published at &lt;a href="https://www.syncfusion.com/blogs/post/universal-doc-viewing-maui-pdf-viewer" rel="noopener noreferrer"&gt;Syncfusion.com.&lt;/a&gt;&lt;/p&gt;

</description>
      <category>dotnetmaui</category>
      <category>crossplatform</category>
      <category>desktop</category>
      <category>documentprocessing</category>
    </item>
    <item>
      <title>What’s New in .NET 11 Preview 1 &amp; 2: Runtime Async, Zstandard, Blazor TempData, and Vector Search</title>
      <dc:creator>Calvince Moth</dc:creator>
      <pubDate>Tue, 07 Apr 2026 06:43:57 +0000</pubDate>
      <link>https://dev.to/syncfusion/whats-new-in-net-11-preview-1-2-runtime-async-zstandard-blazor-tempdata-and-vector-search-5glg</link>
      <guid>https://dev.to/syncfusion/whats-new-in-net-11-preview-1-2-runtime-async-zstandard-blazor-tempdata-and-vector-search-5glg</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt;.NET 11 Preview 1 brings Zstandard compression, AI/ML types, async runtime upgrades, and UI/tooling improvements. Preview 2 extends this with Blazor TempData, OpenTelemetry, EF Core vector search, smaller SDK images, MAUI enhancements, and further performance gains.&lt;/p&gt;

&lt;p&gt;.NET 11 &lt;a href="https://devblogs.microsoft.com/dotnet/dotnet-11-preview-1/" rel="noopener noreferrer"&gt;Preview 1&lt;/a&gt; and &lt;a href="https://devblogs.microsoft.com/dotnet/dotnet-11-preview-2/" rel="noopener noreferrer"&gt;Preview 2&lt;/a&gt; are out, and they’re worth a look if you build high-throughput services, modern web apps with Blazor, or you’re starting to bring AI-ish workloads (embeddings, semantic search, model inference) into “normal” line-of-business systems.&lt;/p&gt;

&lt;p&gt;This post focuses on four updates that materially change what you can do (or how easy it is to do it):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Runtime Async&lt;/strong&gt; (Preview 1, refined in Preview 2).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Native Zstandard (zstd) compression&lt;/strong&gt; (Preview 1).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Blazor TempData for SSR&lt;/strong&gt; (Preview 2).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;EF Core vector search for SQL Server&lt;/strong&gt; (Preview 2).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I’ll also call out a few smaller but meaningful tooling/platform changes at the end.&lt;/p&gt;

&lt;h2&gt;
  
  
  What shipped in Preview 1 vs Preview 2 (quick map)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Preview 1 highlights
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Native &lt;strong&gt;Zstandard (zstd)&lt;/strong&gt; compression APIs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Runtime Async&lt;/strong&gt; foundation (enabled for experimentation via preview features).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;BFloat16&lt;/code&gt; type for AI/ML and numerics scenarios.&lt;/li&gt;
&lt;li&gt;C# preview improvements like collection expression arguments.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Preview 2 highlights
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Blazor TempData&lt;/strong&gt;  support for  &lt;strong&gt;static SSR&lt;/strong&gt; scenarios.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Native OpenTelemetry tracing&lt;/strong&gt; support in ASP.NET Core (baseline enablement).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;EF Core vector search&lt;/strong&gt; support for SQL Server (vector distance + indexing support).&lt;/li&gt;
&lt;li&gt;Runtime Async  &lt;strong&gt;V2 refinements.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Smaller SDK/container images and a bunch of runtime/SDK polish.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Libraries: Powerful new APIs and performance wins
&lt;/h2&gt;

&lt;p&gt;The Base Class Library (BCL) gains several production-ready additions that solve real-world pain points.&lt;/p&gt;

&lt;h3&gt;
  
  
  Zstandard compression support
&lt;/h3&gt;

&lt;p&gt;Need to shrink files or speed up data transfer? .NET now natively supports &lt;a href="https://github.com/dotnet/core/blob/main/release-notes/11.0/preview/preview1/libraries.md#zstandard-compression-support" rel="noopener noreferrer"&gt;Zstandard&lt;/a&gt; (zstd), a modern algorithm that’s often faster than &lt;code&gt;GZip&lt;/code&gt; or &lt;code&gt;Brotli&lt;/code&gt; while keeping excellent compression ratios.&lt;/p&gt;

&lt;p&gt;In web servers, logging pipelines, or big-data scenarios, Zstandard delivers &lt;code&gt;2–7x&lt;/code&gt; faster compression and up to &lt;code&gt;14x&lt;/code&gt; faster decompression (per official &lt;a href="https://github.com/dotnet/runtime/pull/119575" rel="noopener noreferrer"&gt;benchmarks&lt;/a&gt;). Lower latency and storage costs in production.&lt;/p&gt;

&lt;p&gt;Example implementation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.IO.Compression&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// Compress data&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;inputStream&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;OpenRead&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"largefile.txt"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;outputStream&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"compressed.zst"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;compressStream&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ZstandardStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;outputStream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CompressionMode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Compress&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;inputStream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CopyToAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;compressStream&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Decompress&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;decompressInput&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;OpenRead&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"compressed.zst"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;decompressOutput&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"restored.txt"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;decompressStream&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ZstandardStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;decompressInput&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CompressionMode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Decompress&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;decompressStream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CopyToAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;decompressOutput&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F04%2FFiles-Compressed-Using-Zstandard.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F04%2FFiles-Compressed-Using-Zstandard.png" alt="&amp;lt;alt-text&amp;gt;" width="505" height="185"&gt;&lt;/a&gt;&lt;br&gt;Files Compressed Using Zstandard
  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pro tip:&lt;/strong&gt; Pair it with &lt;code&gt;HttpClientHandler.AutomaticDecompression&lt;/code&gt; for automatic &lt;code&gt;zstd&lt;/code&gt; handling in APIs that helps you transmit significantly less data during HTTP data transfers if the payload is compressible.&lt;/p&gt;

&lt;p&gt;Here’s the code example in C#:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;handler&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;HttpClientHandler&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;AutomaticDecompression&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DecompressionMethods&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GZip&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="n"&gt;DecompressionMethods&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Zstandard&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;HttpClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// Automatically decompresses zstd-encoded responses&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"https://example.com"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  BFloat16 floating-point type
&lt;/h3&gt;

&lt;p&gt;Machine-learning models need numbers that balance range and memory. &lt;a href="https://github.com/dotnet/core/blob/main/release-notes/11.0/preview/preview1/libraries.md#bfloat16-floating-point-type" rel="noopener noreferrer"&gt;BFloat16&lt;/a&gt; (16-bit “Brain Float”) gives you the wide range of a regular &lt;code&gt;float&lt;/code&gt; while using half the memory.&lt;/p&gt;

&lt;p&gt;Ideal for tensor operations in &lt;code&gt;ML.NET&lt;/code&gt;, &lt;code&gt;ONNX Runtime&lt;/code&gt;, or custom AI pipelines. Reduced memory footprint = larger models or batches on the same hardware.&lt;/p&gt;

&lt;p&gt;Here’s the example C# code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;BFloat16&lt;/span&gt; &lt;span class="k"&gt;value&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BFloat16&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="m"&gt;3.14f&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;regularFloat&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;float&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Lossless upcast to float&lt;/span&gt;

&lt;span class="c1"&gt;// ML-style computation&lt;/span&gt;
&lt;span class="n"&gt;BFloat16&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BFloat16&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="m"&gt;1.5f&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;BFloat16&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BFloat16&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="m"&gt;2.0f&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;BFloat16&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// 3.0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  C# collection expression arguments
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/dotnet/core/blob/main/release-notes/11.0/preview/preview1/csharp.md#collection-expression-arguments" rel="noopener noreferrer"&gt;Collection expressions&lt;/a&gt; (&lt;code&gt;[]&lt;/code&gt;) just got smarter. You can now pass constructor arguments like capacity or a custom comparer directly inside the brackets. Pre-allocate capacity to avoid reallocations on hot paths; use an immutable &lt;code&gt;FrozenDictionary&lt;/code&gt; or case-insensitive set with zero extra code.&lt;/p&gt;

&lt;p&gt;Example implementation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;values&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"apple"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"banana"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"cherry"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="c1"&gt;// Set initial capacity as twice the capacity for better performance&lt;/span&gt;
&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;names&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;capacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Length&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;..&lt;/span&gt; &lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Case-insensitive HashSet&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;HashSet&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;uniqueNames&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; 
&lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="k"&gt;with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;StringComparer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OrdinalIgnoreCase&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="s"&gt;"Apple"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"apple"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"BANANA"&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;uniqueNames&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// Outputs "Apple" and "BANANA" only once each&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; To enable preview features, you need to set the &lt;code&gt;LangVersion&lt;/code&gt; property to preview in your project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;PropertyGroup&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;LangVersion&amp;gt;&lt;/span&gt;preview&lt;span class="nt"&gt;&amp;lt;/LangVersion&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/PropertyGroup&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Beyond collection expression arguments, extended layout support improves interop scenarios (great for performance-critical libraries). The language team continues making C# more concise and expressive, exactly what both new and veteran developers love.&lt;/p&gt;

&lt;h2&gt;
  
  
  Entity Framework Core improvements
&lt;/h2&gt;

&lt;p&gt;Entity Framework Core continues to evolve in .NET 11 Preview 1 &amp;amp; 2 with several developer-friendly enhancements that make data access more expressive and productive.&lt;/p&gt;

&lt;p&gt;The most notable addition is full support for &lt;a href="https://learn.microsoft.com/en-us/ef/core/what-is-new/ef-core-11.0/whatsnew#complex-types-and-json-columns-on-entity-types-with-tpttpc-inheritance" rel="noopener noreferrer"&gt;complex types and JSON columns&lt;/a&gt; on entity types that use TPT (&lt;code&gt;Table-Per-Type&lt;/code&gt;) or TPC (&lt;code&gt;Table-Per-Concrete-Type&lt;/code&gt;) inheritance mappings. A long-requested capability that lets beginners model real-world hierarchical business objects (like an Animal base class with nested Details stored as JSON) without workarounds, while experienced architects gain powerful flexibility for rich domain-driven designs:&lt;/p&gt;

&lt;p&gt;Here’s the code example in C#:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.EntityFrameworkCore&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.ComponentModel.DataAnnotations.Schema&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;GetAwaiter&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;GetResult&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;abstract&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Animal&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Empty&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;required&lt;/span&gt; &lt;span class="n"&gt;AnimalDetails&lt;/span&gt; &lt;span class="n"&gt;Details&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Dog&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Animal&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;Breed&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Cat&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Animal&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;IsIndoor&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ComplexType&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AnimalDetails&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt; &lt;span class="n"&gt;BirthDate&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;Veterinarian&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ApplicationDbContext&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;DbContext&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;DbSet&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Animal&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Animals&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;ApplicationDbContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DbContextOptions&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ApplicationDbContext&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;base&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;OnModelCreating&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ModelBuilder&lt;/span&gt; &lt;span class="n"&gt;modelBuilder&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// New in .NET 11 / EF Core 11:&lt;/span&gt;
        &lt;span class="c1"&gt;// Complex types can now be stored as JSON columns with TPT/TPC inheritance&lt;/span&gt;
        &lt;span class="n"&gt;modelBuilder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Entity&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Animal&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;()&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseTptMappingStrategy&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ComplexProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Details&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToJson&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

        &lt;span class="n"&gt;modelBuilder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Entity&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Dog&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
        &lt;span class="n"&gt;modelBuilder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Entity&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Cat&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;partial&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;connectionString&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Data Source=SYNCLAPN-44605;Initial Catalog=AnimalDbTest;Integrated Security=True;Encrypt=False"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;DbContextOptionsBuilder&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ApplicationDbContext&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;()&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseSqlServer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;connectionString&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Options&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ApplicationDbContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Create database + tables (perfect for quick testing)&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Database&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;EnsureCreatedAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Database created successfully!\n"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// === INSERT TEST DATA ===&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;dog&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Dog&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Buddy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;Breed&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Labrador"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;Details&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;AnimalDetails&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;BirthDate&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;2022&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;15&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                &lt;span class="n"&gt;Veterinarian&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Dr. Smith"&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;cat&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Cat&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Luna"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;IsIndoor&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;Details&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;AnimalDetails&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;BirthDate&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;2023&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                &lt;span class="n"&gt;Veterinarian&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Dr. John"&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;

        &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Animals&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddRange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dog&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveChangesAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Inserted Dog and Cat successfully!\n"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// === QUERY &amp;amp; DISPLAY ===&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Dogs:"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;dogs&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Animals&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OfType&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Dog&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;().&lt;/span&gt;&lt;span class="nf"&gt;ToListAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;dogs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$" • &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; (&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Breed&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;) - Born: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Details&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BirthDate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;yyyy&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;MM&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;dd&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;, Vet: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Details&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Veterinarian&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"\nCats:"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;cats&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Animals&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OfType&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Cat&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;().&lt;/span&gt;&lt;span class="nf"&gt;ToListAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;cats&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$" • &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; (Indoor: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsIndoor&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;) - Born: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Details&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BirthDate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;yyyy&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;MM&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;dd&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;, Vet: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Details&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Veterinarian&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// See the actual JSON stored in the database&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"\Raw JSON column example (Details column from SQL):"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;raw&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Database&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SqlQueryRaw&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;"SELECT Details FROM Animals WHERE Id = 1"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToListAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;raw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FirstOrDefault&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;??&lt;/span&gt; &lt;span class="s"&gt;"No data"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will create a JSON column (e.g., Details) in the base Animal table while still using separate tables for Dog and Cat (TPT).&lt;/p&gt;

&lt;p&gt;This article was originally published at &lt;a href="https://www.syncfusion.com/blogs/post/dotnet-11-preview-whats-new" rel="noopener noreferrer"&gt;Syncfusion.com.&lt;/a&gt;&lt;/p&gt;

</description>
      <category>dotnet11</category>
      <category>dotnet</category>
      <category>dotnetdevelopment</category>
      <category>dotnetmaui</category>
    </item>
    <item>
      <title>Your Syncfusion License Just Got More Powerful: Code Studio Is Now Included</title>
      <dc:creator>Calvince Moth</dc:creator>
      <pubDate>Mon, 06 Apr 2026 10:05:49 +0000</pubDate>
      <link>https://dev.to/syncfusion/your-syncfusion-license-just-got-more-powerful-code-studio-is-now-included-44pj</link>
      <guid>https://dev.to/syncfusion/your-syncfusion-license-just-got-more-powerful-code-studio-is-now-included-44pj</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Code Studio is now included for Syncfusion license holders, offering AI-assisted development with 5,000 starter credits (for paid users), flexible credit usage, and team support. Activate your access and start building faster with intelligent code generation.&lt;/p&gt;

&lt;p&gt;What if your existing &lt;a href="https://www.syncfusion.com/" rel="noopener noreferrer"&gt;Syncfusion&lt;sup&gt;®&lt;/sup&gt;&lt;/a&gt; license could do more than just give you UI components?&lt;/p&gt;

&lt;p&gt;What if it could also help you generate code, accelerate development, and reduce repetitive work, without any additional cost?&lt;/p&gt;

&lt;p&gt;That’s exactly what’s changing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.syncfusion.com/code-studio/" rel="noopener noreferrer"&gt;Code Studio&lt;/a&gt; is now &lt;strong&gt;free for Syncfusion license holders&lt;/strong&gt;, bringing AI-assisted development directly into your workflow. Whether you’re building enterprise applications or experimenting with new ideas, you can now move faster with tools designed to support modern development.&lt;/p&gt;

&lt;p&gt;In this blog, we’ll walk through what Code Studio offers, what’s included in the free plans, and how you can start using it today.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Code Studio?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Code Studio&lt;/strong&gt; is Syncfusion’s AI-powered development environment that helps developers move from idea to implementation faster.&lt;/p&gt;

&lt;p&gt;It is designed to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Accelerate UI development.&lt;/li&gt;
&lt;li&gt;Generate production-ready code.&lt;/li&gt;
&lt;li&gt;Reduce repetitive development tasks.&lt;/li&gt;
&lt;li&gt;Work seamlessly with Syncfusion components.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of switching between tools or manually configuring components, Code Studio helps you &lt;strong&gt;generate&lt;/strong&gt;, &lt;strong&gt;refine&lt;/strong&gt;, and &lt;strong&gt;build&lt;/strong&gt;, all in one place.&lt;/p&gt;

&lt;h2&gt;
  
  
  Free access for Syncfusion users
&lt;/h2&gt;

&lt;p&gt;Code Studio is now available at no cost under two plans, depending on your Syncfusion license.&lt;/p&gt;

&lt;h3&gt;
  
  
  Syncfusion paid license plan
&lt;/h3&gt;

&lt;p&gt;If your organization has an active Syncfusion license, you can now unlock Code Studio for your entire team.&lt;/p&gt;

&lt;h4&gt;
  
  
  What’s included
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Free access for up to 100 developers.&lt;/li&gt;
&lt;li&gt;5,000 starter credits (first month only).&lt;/li&gt;
&lt;li&gt;Standard SLA support.&lt;/li&gt;
&lt;li&gt;Full integration with your Syncfusion ecosystem.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  A flexible credit system
&lt;/h4&gt;

&lt;p&gt;Code Studio introduces a usage-based model that gives you flexibility without pressure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Start with free credits&lt;/strong&gt;
Eligible customers receive 5,000 starter credits to begin exploring immediately.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use credits with confidence&lt;/strong&gt;
Unused credits roll over, allowing you to use them over time as long as your account remains active.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scale when needed&lt;/strong&gt;
You can top up credits at any time based on your project requirements.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Built for teams&lt;/strong&gt;
Add up to 100 developers and collaborate within a shared AI-assisted environment.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Why this matters
&lt;/h4&gt;

&lt;p&gt;This plan enables teams to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Prototype and build applications faster.&lt;/li&gt;
&lt;li&gt;Reduce manual effort through AI-assisted code generation.&lt;/li&gt;
&lt;li&gt;Scale usage without upfront investment.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Start here by signing in to your &lt;a href="https://app.sfcodestudio.com/settings?tab=billing" rel="noopener noreferrer"&gt;Code Studio account&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Syncfusion community license plan
&lt;/h3&gt;

&lt;p&gt;For individual developers and small teams, Code Studio is also available under the Community License.&lt;/p&gt;

&lt;h4&gt;
  
  
  What’s included
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Free access for up to 5 developers.&lt;/li&gt;
&lt;li&gt;Full access to Code Studio features.&lt;/li&gt;
&lt;li&gt;Standard SLA support.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Things to note
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Starter credits are not included.&lt;/li&gt;
&lt;li&gt;Additional usage follows standard pricing.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Why this matters
&lt;/h4&gt;

&lt;p&gt;This plan is ideal for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Exploring AI-assisted development.&lt;/li&gt;
&lt;li&gt;Learning Syncfusion components more efficiently.&lt;/li&gt;
&lt;li&gt;Building prototypes and MVPs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Activate the Community License and build faster with &lt;a href="https://app.sfcodestudio.com/settings?tab=billing" rel="noopener noreferrer"&gt;Code Studio&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Comparing the plans
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Feature&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Paid License&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Community License&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Developer Limit&lt;/td&gt;
&lt;td&gt;Up to 100&lt;/td&gt;
&lt;td&gt;Up to 5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cost&lt;/td&gt;
&lt;td&gt;Free&lt;/td&gt;
&lt;td&gt;Free&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Starter Credits&lt;/td&gt;
&lt;td&gt;5,000 (first month)&lt;/td&gt;
&lt;td&gt;Not included&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Credit Rollover&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SLA&lt;/td&gt;
&lt;td&gt;Standard&lt;/td&gt;
&lt;td&gt;Standard&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Why developers will benefit
&lt;/h2&gt;

&lt;p&gt;Code Studio is not just another tool; it’s designed to improve how teams build applications.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Faster development&lt;/strong&gt;
Generate UI and logic quickly using AI-assisted workflows.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Built for Syncfusion components&lt;/strong&gt;
Code follows best practices with correct APIs and configurations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flexible usage model&lt;/strong&gt;
Credits roll over, can be topped up at any time, and you only pay when scaling.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Team-ready environment&lt;/strong&gt;
Supports collaboration across up to 100 developers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Improved productivity&lt;/strong&gt;
Reduce iteration cycles and focus on delivering features.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to activate your Code Studio access
&lt;/h2&gt;

&lt;p&gt;Getting started with Code Studio is straightforward:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Sign in to Code Studio.&lt;/li&gt;
&lt;li&gt;Navigate to &lt;strong&gt;Settings → Billing.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Activate your eligible plan.&lt;/li&gt;
&lt;li&gt;Start building with AI-assisted development.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You can also get direct access to Code Studio through the &lt;a href="https://app.sfcodestudio.com/settings?tab=billing" rel="noopener noreferrer"&gt;billing page&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Making the most of your access
&lt;/h2&gt;

&lt;p&gt;To maximize the value of Code Studio:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use starter credits to explore advanced capabilities.&lt;/li&gt;
&lt;li&gt;Generate Syncfusion UI components efficiently.&lt;/li&gt;
&lt;li&gt;Prototype dashboards and real-world applications.&lt;/li&gt;
&lt;li&gt;Build reusable templates for your team.&lt;/li&gt;
&lt;li&gt;Scale usage with credit top-ups as your needs grow.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because unused credits roll over, you can explore features without time pressure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final thoughts
&lt;/h2&gt;

&lt;p&gt;With this update, Syncfusion extends its ecosystem beyond components, bringing AI-assisted development directly into your workflow.&lt;/p&gt;

&lt;p&gt;Whether you’re part of a large organization or a small team, Syncfusion &lt;a href="https://www.syncfusion.com/code-studio/" rel="noopener noreferrer"&gt;Code Studio&lt;/a&gt; enables you to build faster, reduce manual effort, and scale efficiently, without disrupting the way you already work.&lt;/p&gt;

&lt;h3&gt;
  
  
  Get started today
&lt;/h3&gt;

&lt;p&gt;Getting started with Code Studio is simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Activate your free access in &lt;a href="https://app.sfcodestudio.com/settings?tab=billing" rel="noopener noreferrer"&gt;Code Studio&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Begin using your 5,000 starter credits (if eligible).&lt;/li&gt;
&lt;li&gt;Invite your team and begin collaborating.&lt;/li&gt;
&lt;li&gt;Scale your usage with flexible credit top-ups as needed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you’re already using Syncfusion, this is a natural next step to enhance your development workflow.&lt;/p&gt;

&lt;p&gt;Need help? Reach us through the &lt;a href="https://www.syncfusion.com/forums" rel="noopener noreferrer"&gt;support forum&lt;/a&gt;, &lt;a href="https://support.syncfusion.com/" rel="noopener noreferrer"&gt;support portal&lt;/a&gt;, or &lt;a href="https://www.syncfusion.com/feedback" rel="noopener noreferrer"&gt;feedback portal&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Start building smarter with Syncfusion Code Studio today!&lt;/p&gt;

&lt;p&gt;This article was originally published at &lt;a href="https://www.syncfusion.com/blogs/post/syncfusion-license-with-code-studio" rel="noopener noreferrer"&gt;Syncfusion.com.&lt;/a&gt;&lt;/p&gt;

</description>
      <category>syncfusioncodestudio</category>
      <category>aicodeeditor</category>
      <category>aicodereview</category>
      <category>aidevelopment</category>
    </item>
  </channel>
</rss>
