Description
What happened?
I'm using a WPF WebView2CompositionControl
to display an instance of Monaco Editor, but the content is blurry. It looks like the content is rendered for a wrong DPI value.
At first I used the WebView2
control but this control has the issue that it is always shown on top of all other WPF controls. So I switched to the WebView2CompositionControl
, the overlaying issue is fixed now, but the content is blurred. This was not the case when I used the WebView2
control.
Importance
Moderate. My app's user experience is affected, but still usable.
Runtime Channel
Stable release (WebView2 Runtime)
Runtime Version
No response
SDK Version
No response
Framework
WPF
Operating System
Windows 11
OS Version
No response
Repro steps
Steps to reproduce
Use this HTML for Monaco editor:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Editor</title>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<link rel="stylesheet"
data-name="vs/editor/editor.main"
href="./min/vs/editor/editor.main.css"/>
<style>
html, body {
height: 100%;
margin: 0;
}
#container {
height: 100%;
}
</style>
</head>
<body>
<div id="container"></div>
<script src="./min/vs/loader.js"></script>
<script>
require.config({paths: {'vs': './min/vs'}});
</script>
<script src="./min/vs/editor/editor.main.js"></script>
<script>
// Hold a reference to the Monaco editor instance
let monacoEditor;
// Function to initialize the editor
function initializeEditor(content, theme = 'vs-light') {
require(['vs/editor/editor.main'], function () {
if (monacoEditor) {
return;
}
monacoEditor = monaco.editor.create(document.getElementById('container'), {
value: content.toString(),
automaticLayout: true,
theme: theme,
});
});
// Add a resize listener to resize Monaco Editor dynamically
window.addEventListener('resize', () => {
if (monacoEditor) {
monacoEditor.layout();
}
});
}
</script>
</body>
</html>
Use this WPF XAML:
<UserControl
x:Class="Example.TextEditor"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:wpf="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf"
d:DesignHeight="300"
d:DesignWidth="300"
mc:Ignorable="d">
<Grid>
<wpf:WebView2CompositionControl
x:Name="TextEditorView"
NavigationCompleted="TextEditorView_OnNavigationCompleted" />
</Grid>
</UserControl>
Code behind:
using CommunityToolkit.Mvvm.Input;
using Microsoft.Web.WebView2.Core;
using Microsoft.Web.WebView2.Wpf;
using System;
using System.IO;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using JsonSerializer = System.Text.Json.JsonSerializer;
namespace Example.TextEditor;
public partial class TextEditor : UserControl
{
public TextEditor()
{
InitializeComponent();
TextEditorView.Source = new Uri(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Monaco\editor.html"));
}
private async Task InitializeEditorAsync()
{
if (_isEditorInitialized)
{
return;
}
var javaScriptString = ConvertToJavaScriptString(Text);
var script = $"initializeEditor({javaScriptString})";
await ExecuteJavaScriptAsync(script, TextEditorView);
_isEditorInitialized = true;
}
private async Task<string> ExecuteJavaScriptAsync(string script, WebView2CompositionControl webview)
{
await webview.EnsureCoreWebView2Async();
// Call the script in the WebView2 (this executes in the loaded HTML/JS context)
var result = await webview.CoreWebView2.ExecuteScriptAsync(script);
if (!string.IsNullOrEmpty(result))
{
result = ConvertToCSharpString(result);
}
return result;
}
private string ConvertToJavaScriptString(string text)
{
// JSON is compatible to JavaScript
return JsonSerializer.Serialize(text);
}
private string ConvertToCSharpString(string javaScriptString)
{
// JSON is compatible to JavaScript
return JsonSerializer.Deserialize<string>(javaScriptString);
}
private async void TextEditorView_OnNavigationCompleted(object sender, CoreWebView2NavigationCompletedEventArgs e)
{
try
{
await InitializeEditorAsync();
}
catch (Exception exception)
{
Console.WriteLine(exception);
}
}
}
Expected Behavior
WebView2CompositionControl
displays the HTML content exactly as the WebView2
control correctly rendered.
Actual Behavior
WebView2CompositionControl
displays the HTML content blurred.
Repros in Edge Browser
No, issue does not reproduce in the corresponding Edge version
Regression
No, this never worked
Last working version (if regression)
No response