-
Notifications
You must be signed in to change notification settings - Fork 1
Add documentation for CodeEditor control #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
sergepilipchuk
merged 5 commits into
DevExpress-Examples:26.1.1+
from
sergepilipchuk:sp-add-doc-26.1.1+
Jun 29, 2026
Merged
Changes from 3 commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
1cac576
Add documentation for CodeEditor control
sergepilipchuk 3b39c07
Update theming snippet in Overview docs
sergepilipchuk 0e34f8f
Update CodeEditor docs formatting and wording
sergepilipchuk 32486ca
Apply suggestions from code review
sergepilipchuk 5b827b0
Apply suggestions from code review
sergepilipchuk File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,70 @@ | ||
| # CodeEditor | ||
|
|
||
| WPF control that embeds Monaco Editor (VS Code editor) using WebView2 for code editing with syntax highlighting. | ||
|
|
||
| ## Properties | ||
|
|
||
| | Name | Type | Description | | ||
| | ---- | ---- | ----------- | | ||
| | `Text` | `string` | Gets or sets editor text. This is a dependency property. Supports two-way binding. | | ||
|
sergepilipchuk marked this conversation as resolved.
Outdated
|
||
| | `EditorLanguage` | `string` | Gets or sets the programming language for syntax highlighting. This is a dependency property. Default: `"csharp"` | | ||
| | `ReadOnly` | `bool` | Gets or sets whether the editor is read-only. This is a dependency property. Default: `false` | | ||
| | `IsModified` | `bool` | Gets whether the content has been modified since the last save. This is a readonly dependency property. | | ||
|
sergepilipchuk marked this conversation as resolved.
Outdated
|
||
| | `ShowLineNumbers` | `bool` | Gets or sets whether line numbers are displayed. This is a dependency property. Default: `true` | | ||
| | `LineNumbersMinChars` | `int` | Gets or sets the minimum number of character slots reserved for the line-number gutter. This is a dependency property. Default: `5` | | ||
|
sergepilipchuk marked this conversation as resolved.
Outdated
|
||
| | `ShowMinimap` | `bool` | Gets or sets whether the minimap is displayed. This is a dependency property. Default: `false` | | ||
| | `ShowGlyphMargin` | `bool` | Gets or sets whether the glyph margin is displayed. This is a dependency property. Default: `false` | | ||
| | `EnableFolding` | `bool` | Gets or sets whether code folding is enabled. This is a dependency property. Default: `true` | | ||
| | `TabSize` | `int` | Gets or sets the tab size in spaces (1-64). This is a dependency property. Default: `4` | | ||
| | `InsertSpaces` | `bool` | Gets or sets whether spaces are inserted instead of tabs. This is a dependency property. Default: `true` | | ||
| | `DetectIndentation` | `bool` | Gets or sets whether indentation is detected from file content. This is a dependency property. Default: `true` | | ||
| | `AutoIndent` | `EditorAutoIndent` | Gets or sets auto-indentation mode. This is a dependency property. Default: `EditorAutoIndent.Full` | | ||
|
sergepilipchuk marked this conversation as resolved.
Outdated
|
||
| | `WordWrap` | `EditorWordWrap` | Gets or sets word wrap mode. This is a dependency property. Default: `EditorWordWrap.Off` | | ||
|
sergepilipchuk marked this conversation as resolved.
Outdated
|
||
| | `EnableScrollBeyondLastLine` | `bool` | Gets or sets whether scrolling beyond the last line is allowed. This is a dependency property. Default: `true` | | ||
| | `ScrollBeyondLastColumn` | `int` | Gets or sets the number of columns to scroll beyond the last character. This is a dependency property. Default: `5` | | ||
|
sergepilipchuk marked this conversation as resolved.
Outdated
|
||
| | `EnableSmoothScrolling` | `bool` | Gets or sets whether smooth scrolling is enabled. This is a dependency property. Default: `false` | | ||
| | `EnableStickyScroll` | `bool` | Gets or sets whether sticky scroll is enabled. This is a dependency property. Default: `true` | | ||
| | `EnableContextMenu` | `bool` | Gets or sets whether the context menu is enabled. This is a dependency property. Default: `true` | | ||
| | `EnableDragAndDrop` | `bool` | Gets or sets whether drag and drop is enabled. This is a dependency property. Default: `true` | | ||
| | `EnableMouseWheelZoom` | `bool` | Gets or sets whether zooming with <kbd>Ctrl</kbd>+<kbd>MouseWheel</kbd> is enabled. This is a dependency property. Default: `false` | | ||
| | `EnableQuickSuggestions` | `bool` | Gets or sets whether quick suggestions are enabled. This is a dependency property. Default: `true` | | ||
| | `EnableWordBasedSuggestions` | `bool` | Gets or sets whether word-based suggestions are enabled. This is a dependency property. Default: `true` | | ||
| | `EnableSuggestOnTriggerCharacters` | `bool` | Gets or sets whether suggestions appear automatically when typing trigger characters. This is a dependency property. Default: `true` | | ||
|
sergepilipchuk marked this conversation as resolved.
Outdated
|
||
| | `EnableParameterHints` | `bool` | Gets or sets whether parameter hints are displayed. This is a dependency property. Default: `true` | | ||
| | `ThemeName` | `string` | Gets or sets the Monaco Editor theme name. This is a dependency property. Default: `"vs"` | | ||
| | `MarkAsSavedCommand` | `ICommand` | Gets the command that resets the `IsModified` flag. | | ||
|
|
||
| ## Methods | ||
|
|
||
| | Name | Description | | ||
| | ---- | ----------- | | ||
| | `GetAvailableLanguagesAsync(CancellationToken)` | Asynchronously retrieves a list of available programming language IDs. | | ||
| | `RegisterLanguage(LanguageDescriptor)` | Registers a custom programming language with Monarch tokenizer. | | ||
|
sergepilipchuk marked this conversation as resolved.
Outdated
|
||
| | `RegisterTheme(MonacoTheme)` | Registers a custom Monaco Editor theme. | | ||
| | `MarkAsSaved()` | Resets the `IsModified` property to `false`. | | ||
| | `Dispose()` | Releases WebView2 resources. | | ||
|
|
||
| ## Events | ||
|
|
||
| | Name | Description | | ||
| | ---- | ----------- | | ||
| | `EditorInitialized` | Occurs when the Monaco Editor is fully initialized and ready for commands. | | ||
|
|
||
| ## Enums | ||
|
|
||
| ### EditorAutoIndent | ||
|
|
||
| | Member | Description | | ||
| | ------ | ----------- | | ||
| | `None` | No automatic indentation | | ||
| | `Keep` | Keep current indentation | | ||
| | `Brackets` | Indent based on brackets | | ||
| | `Advanced` | Advanced indentation | | ||
| | `Full` | Full automatic indentation (recommended) | | ||
|
|
||
| ### EditorWordWrap | ||
|
|
||
| | Member | Description | | ||
| | ------ | ----------- | | ||
| | `Off` | No word wrapping | | ||
| | `On` | Word wrapping enabled | | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| # CodeEditorService | ||
|
|
||
| MVVM service that provides access to CodeEditor control functionality from ViewModels. | ||
|
|
||
| ## Interface | ||
|
|
||
| ```csharp | ||
| public interface ICodeEditorService { | ||
| void MarkAsSaved(); | ||
| Task<IReadOnlyCollection<string>> GetLanguagesAsync(CancellationToken cancellationToken = default); | ||
| void RegisterLanguage(LanguageDescriptor language); | ||
| } | ||
| ``` | ||
|
|
||
| ## Methods | ||
|
|
||
| | Name | Description | | ||
| | ---- | ----------- | | ||
| | `MarkAsSaved()` | Resets the `IsModified` flag of the associated `CodeEditor` to `false`. | | ||
| | `GetLanguagesAsync(CancellationToken)` | Asynchronously retrieves a collection of available programming language IDs from the associated `CodeEditor`. | | ||
| | `RegisterLanguage(LanguageDescriptor)` | Registers a custom programming language with Monarch tokenizer in the associated `CodeEditor`. | | ||
|
sergepilipchuk marked this conversation as resolved.
Outdated
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,292 @@ | ||
| ## Introduction | ||
|
|
||
| `CodeEditor` is a WPF control that embeds the [Monaco Editor](https://microsoft.github.io/monaco-editor/) (the editor engine used by Visual Studio Code) using [Microsoft WebView2](https://learn.microsoft.com/en-us/microsoft-edge/webview2/). | ||
|
sergepilipchuk marked this conversation as resolved.
Outdated
|
||
|
|
||
| The editor includes modern code editing capabilities — syntax highlighting, folding, minimap, theming, and custom languages — within WPF applications. | ||
|
sergepilipchuk marked this conversation as resolved.
Outdated
|
||
|
|
||
| The primary editing surface is the `CodeEditor` control, which exposes a focused, WPF-friendly API. | ||
|
sergepilipchuk marked this conversation as resolved.
Outdated
|
||
|
|
||
| The library also includes: | ||
|
sergepilipchuk marked this conversation as resolved.
Outdated
|
||
|
|
||
| - `ThemeBehavior` - integrates Monaco with DevExpress themes. | ||
| - `CodeEditorService` - a lightweight service for cases where direct interaction with the control is not sufficient. | ||
|
sergepilipchuk marked this conversation as resolved.
Outdated
|
||
|
|
||
| The control is designed as a **state-driven wrapper**: WPF owns the editor state through dependency properties, and Monaco reflects that state while propagating changes back to WPF in an MVVM-friendly way. | ||
|
sergepilipchuk marked this conversation as resolved.
Outdated
|
||
|
|
||
| > **Supported Monaco version:** 0.55.1 | ||
| > The control is built and validated against this specific release. | ||
|
sergepilipchuk marked this conversation as resolved.
Outdated
|
||
|
|
||
| ## Prerequisites | ||
|
|
||
| - Windows with [Microsoft Edge WebView2 Runtime](https://learn.microsoft.com/en-us/microsoft-edge/webview2/concepts/distribution) | ||
| - DevExpress WPF **26.1** (or newer compatible version) | ||
|
|
||
| The required .NET version depends on the DevExpress WPF version in use. | ||
| See DevExpress documentation: | ||
| [WPF Controls → Prerequisites → .NET / .NET Core](https://docs.devexpress.com/WPF/8091/prerequisites#netnet-core) | ||
|
sergepilipchuk marked this conversation as resolved.
Outdated
|
||
|
|
||
| > The `CodeEditor` project must be compiled against the same DevExpress WPF version that is used in the consuming application. | ||
|
|
||
| ## Quick Start | ||
|
|
||
| ### 1. Add the `CodeEditor` project | ||
|
|
||
| Add the `CodeEditor` project to your solution and reference it from your WPF application: | ||
|
|
||
| - Add existing project → `CodeEditor` | ||
| - Add project reference from your WPF app | ||
| - Ensure DevExpress WPF and WebView2 dependencies are resolved | ||
|
|
||
| ### 2. Declare the XML namespace | ||
|
|
||
| ```xml | ||
| <Window | ||
| x:Class="YourApp.MainWindow" | ||
| xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | ||
| xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | ||
| xmlns:ce="clr-namespace:CodeEditor;assembly=CodeEditor"> | ||
|
|
||
| <Grid> | ||
| <ce:CodeEditor | ||
| Text="{Binding Code, Mode=TwoWay}" | ||
| EditorLanguage="csharp" | ||
| ThemeName="vs-dark" /> | ||
| </Grid> | ||
|
|
||
| </Window> | ||
| ``` | ||
|
|
||
| ### 3. Create a ViewModel | ||
|
|
||
| ```csharp | ||
| using DevExpress.Mvvm; | ||
|
|
||
| public class MainViewModel : BindableBase | ||
| { | ||
| private string _code = @"using System; | ||
|
|
||
| class Program | ||
| { | ||
| static void Main() | ||
| { | ||
| Console.WriteLine(""Hello, Monaco!""); | ||
| } | ||
| }"; | ||
|
|
||
| public string Code | ||
| { | ||
| get => _code; | ||
| set => SetProperty(ref _code, value); | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| Set the `DataContext` of the window to an instance of `MainViewModel`. | ||
|
|
||
| The editor content is automatically synchronized with the bound property. | ||
|
|
||
| > **Note:** | ||
| > `CodeEditor` does not automatically track DevExpress theme changes. | ||
| > To synchronize Monaco with the active DevExpress theme, use `ThemeBehavior`. | ||
|
|
||
| ## Theming | ||
|
|
||
| `CodeEditor` supports built-in Monaco themes, DevExpress theme integration, and custom theme registration. | ||
|
|
||
| ### Built-in Monaco Themes | ||
|
|
||
| You can use any of the standard Monaco themes: | ||
|
sergepilipchuk marked this conversation as resolved.
Outdated
|
||
|
|
||
| ```csharp | ||
| editor.ThemeName = "vs"; | ||
| editor.ThemeName = "vs-dark"; | ||
| editor.ThemeName = "hc-black"; | ||
| ``` | ||
|
|
||
| These themes are provided by Monaco. | ||
|
sergepilipchuk marked this conversation as resolved.
Outdated
|
||
|
|
||
| ### DevExpress Theme Integration | ||
|
|
||
| By default, `CodeEditor` does not automatically track DevExpress theme changes. | ||
|
sergepilipchuk marked this conversation as resolved.
Outdated
|
||
|
|
||
| To synchronize Monaco with the active DevExpress theme, attach `ThemeBehavior`: | ||
|
sergepilipchuk marked this conversation as resolved.
Outdated
|
||
|
|
||
| ```xml | ||
| xmlns:ce="clr-namespace:CodeEditor;assembly=CodeEditor" | ||
| xmlns:cet="clr-namespace:CodeEditor.Theming;assembly=CodeEditor" | ||
| xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm" | ||
|
|
||
| ... | ||
|
|
||
| <ce:CodeEditor | ||
| Text="{Binding Code}" | ||
| EditorLanguage="csharp"> | ||
|
|
||
| <dxmvvm:Interaction.Behaviors> | ||
| <cet:ThemeBehavior ApplyDevExpressColors="True" /> | ||
| </dxmvvm:Interaction.Behaviors> | ||
|
|
||
| </ce:CodeEditor> | ||
| ``` | ||
|
|
||
| `ThemeBehavior`: | ||
|
sergepilipchuk marked this conversation as resolved.
Outdated
|
||
|
|
||
| - Detects the current DevExpress theme | ||
|
sergepilipchuk marked this conversation as resolved.
Outdated
|
||
| - Resolves Light / Dark / High Contrast base | ||
| - Registers and applies a corresponding Monaco theme | ||
| - Optionally maps DevExpress palette colors to Monaco color keys via the `ApplyDevExpressColors` property | ||
|
|
||
| The theme is updated automatically when the DevExpress theme changes. | ||
|
sergepilipchuk marked this conversation as resolved.
Outdated
|
||
|
|
||
| ### Custom Themes | ||
|
|
||
| You can register a custom Monaco theme programmatically: | ||
|
|
||
| ```csharp | ||
| var theme = new MonacoTheme | ||
| { | ||
| Name = "my-theme", | ||
| Base = MonacoThemeBase.Dark, | ||
| Colors = new Dictionary<string, Color> | ||
| { | ||
| ["editor.background"] = Color.FromRgb(30, 30, 30), | ||
| ["editor.foreground"] = Color.FromRgb(220, 220, 220) | ||
| } | ||
| }; | ||
|
|
||
| editor.RegisterTheme(theme); | ||
| editor.ThemeName = "my-theme"; | ||
| ``` | ||
|
|
||
| For a complete list of commonly used Monaco theme color keys, see the official VS Code theme color reference (Monaco uses the same keys): [Theme Color](https://code.visualstudio.com/api/references/theme-color). | ||
|
|
||
| ### Rules | ||
|
|
||
| In addition to UI colors, Monaco themes support token-level styling via `Rules`. | ||
|
|
||
| Rules define how specific token types (such as `keyword`, `comment`, `string`, and other) are rendered. | ||
|
sergepilipchuk marked this conversation as resolved.
Outdated
|
||
|
|
||
| You can use `Rules` to override the appearance of existing token types or to define styling for custom tokens introduced by a custom language definition. | ||
|
|
||
| ```csharp | ||
| var theme = new MonacoTheme | ||
| { | ||
| Name = "my-theme", | ||
| Base = MonacoThemeBase.Dark, | ||
| Rules = new[] | ||
| { | ||
| new MonacoThemeRule | ||
| { | ||
| Token = "keyword", | ||
| Foreground = Color.FromRgb(86, 156, 214), | ||
| FontStyle = MonacoFontStyle.Bold | ||
| }, | ||
| new MonacoThemeRule | ||
| { | ||
| Token = "comment", | ||
| Foreground = Color.FromRgb(106, 153, 85), | ||
| FontStyle = MonacoFontStyle.Italic | ||
| } | ||
| } | ||
| }; | ||
| ``` | ||
|
|
||
| `Rules` is an init-only property and must be provided during theme initialization. | ||
|
|
||
| If you use `ThemeBehavior`, token styling can also be supplied through its `Rules` property, and it allows rule customization alongside DevExpress theme integration. | ||
|
|
||
| ## Languages | ||
|
|
||
| `CodeEditor` supports both built-in Monaco languages and custom language registration. | ||
|
|
||
| ### Built-in Languages | ||
|
|
||
| To use a built-in Monaco language, specify the `EditorLanguage` property: | ||
|
|
||
| ```csharp | ||
| editor.EditorLanguage = "csharp"; | ||
| editor.EditorLanguage = "javascript"; | ||
| editor.EditorLanguage = "json"; | ||
| ``` | ||
|
|
||
| The value must match a language ID supported in Monaco Editor. | ||
|
sergepilipchuk marked this conversation as resolved.
Outdated
|
||
|
|
||
| ### Custom Languages | ||
|
|
||
| You can register custom languages using `LanguageDescriptor`: | ||
|
|
||
| ```csharp | ||
| var language = new LanguageDescriptor | ||
| { | ||
| Id = "mylang", | ||
|
|
||
| Monarch = @"{ | ||
| tokenizer: { | ||
| root: [ | ||
| [/\b(if|else|while)\b/, 'keyword'], | ||
| [/\/\/.*$/, 'comment'], | ||
| [/"".*?""/, 'string'], | ||
| [/\d+/, 'number'] | ||
| ] | ||
| } | ||
| }", | ||
|
|
||
| Configuration = @"{ | ||
| comments: { | ||
| lineComment: '//' | ||
| }, | ||
| brackets: [ | ||
| ['{', '}'], | ||
| ['[', ']'], | ||
| ['(', ')'] | ||
| ] | ||
| }" | ||
| }; | ||
|
|
||
| editor.RegisterLanguage(language); | ||
| editor.EditorLanguage = "mylang"; | ||
| ``` | ||
|
|
||
| ### Monarch Definition | ||
|
|
||
| The `Monarch` property defines the syntax highlighting rules. | ||
|
sergepilipchuk marked this conversation as resolved.
Outdated
|
||
|
|
||
| The property must contain a valid Monaco Monarch tokenizer definition specified as a JavaScript object literal. | ||
|
|
||
| All standard Monarch features are supported: | ||
|
|
||
| - Multiple states | ||
| - Nested states | ||
| - Regular expressions | ||
| - Rule objects | ||
| - Includes and state transitions | ||
|
|
||
| Refer to the following topic for additional information: [Monarch Documentation](https://microsoft.github.io/monaco-editor/monarch.html) | ||
|
sergepilipchuk marked this conversation as resolved.
Outdated
|
||
|
|
||
| ### Language Configuration | ||
|
|
||
| The optional `Configuration` property defines editor behavior such as: | ||
|
sergepilipchuk marked this conversation as resolved.
Outdated
|
||
|
|
||
| - Line and block comments | ||
| - Brackets | ||
| - Auto-closing pairs | ||
| - Surrounding pairs | ||
|
|
||
| The configuration must also be provided as a JavaScript object literal. | ||
|
|
||
| For language configuration details (brackets, comments, auto-closing pairs, etc.), | ||
| refer to the following topic: [Language Configuration Guide](https://code.visualstudio.com/api/language-extensions/language-configuration-guide) | ||
|
sergepilipchuk marked this conversation as resolved.
Outdated
|
||
|
|
||
| ## See also | ||
|
|
||
| ### API Reference | ||
|
|
||
| - [CodeEditor API Reference](CodeEditor.md) | ||
| - [CodeEditorService API Reference](CodeEditorService.md) | ||
| - [ThemeBehavior API Reference](ThemeBehavior.md) | ||
|
|
||
| ### Monaco Resources | ||
|
|
||
| - [Monaco Editor](https://microsoft.github.io/monaco-editor/) | ||
| - [Monarch Documentation](https://microsoft.github.io/monaco-editor/monarch.html) | ||
| - [Monaco Playground – Custom Languages Example](https://microsoft.github.io/monaco-editor/playground.html?source=v0.55.1#example-extending-language-services-custom-languages) | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.