In my WPF application I need to show an html string, and I know that I need to call EnsureCoreWebView2Async method before calling NavigateToString because otherwise the CoreWebView will be null and I would have an exception. The problem is that awaiting EnsureCoreWebView2Async never ends.
I created a little application in order to reproduce the problem (and excluding issues related to my big project) and the problem is the same.
Here are the code for the sample application (I main window with 2 buttons, one that opens the url and one that load the html string - the first one works):
<Window x:Class="WebViewApp.MainWindow"
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:local="clr-namespace:WebViewApp" xmlns:wpf="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<StackPanel>
<Button Width="200" Height="40" Click="OpenUrl_Click">Open url</Button>
<Button Width="200" Height="40" Click="OpenHtml_Click">Open html</Button>
</StackPanel></Window>
MainWindow behind code:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private async void OpenUrl_Click(object sender, RoutedEventArgs e)
{
var browserWindow = new WebWindow();
//await browserWindow.Initialize(); // this also never completes
browserWindow.OpenUrl("http://www.microsoft.com");
browserWindow.Show();
}
private async void OpenHtml_Click(object sender, RoutedEventArgs e)
{
var browserWindow = new WebWindow();
await browserWindow.Initialize();
browserWindow.LoadHtml(@"<html><head><title>Test title</title></head><body><p>Test</p></body></html>");
browserWindow.Show();
}
}
Here is the browserView xaml (add the WebView2 nuget package):
<Window x:Class="WebViewApp.WebWindow"
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:local="clr-namespace:WebViewApp" xmlns:wpf="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf"
mc:Ignorable="d"
Title="WebWindow" Height="450" Width="800">
<Grid>
<wpf:WebView2 Name="WpfBrowser" />
</Grid></Window>
and the code behind:
public partial class WebWindow : Window
{
public WebWindow()
{
InitializeComponent();
}
public async Task Initialize()
{
try
{
await WpfBrowser.EnsureCoreWebView2Async(); // never completes
}
catch (Exception exception)
{
Console.WriteLine(exception.Message);
}
}
public void LoadHtml(string html)
{
WpfBrowser.NavigateToString(html);
}
public void OpenUrl(string url)
{
WpfBrowser.Source = new Uri(url);
}
}
I also tried to change the Target platform, but nothing changed.
You should defer to initialize the webview until OnContentRendered is called. I changed your code and it worked as a charm. See the changes below.
public partial class WebWindow : Window
{
private string _url;
private string _html;
public WebWindow()
{
InitializeComponent();
}
protected override async void OnContentRendered(EventArgs e)
{
base.OnContentRendered(e);
try
{
var webView2Environment = await CoreWebView2Environment.CreateAsync();
await WpfBrowser.EnsureCoreWebView2Async(webView2Environment);
if(!string.IsNullOrEmpty(_url))
WpfBrowser.Source = new Uri(_url);
else if(!string.IsNullOrEmpty(_html))
WpfBrowser.NavigateToString(_html);
}
catch (Exception exception)
{
Console.WriteLine(exception.Message);
}
}
public void ShowFromUrl(string url)
{
_url = url;
Show();
}
public void ShowFromHtml(string html)
{
_html = html;
Show();
}
}
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private async void OpenUrl_Click(object sender, RoutedEventArgs e)
{
var browserWindow = new WebWindow();
browserWindow.ShowFromUrl("http://www.microsoft.com");
}
private async void OpenHtml_Click(object sender, RoutedEventArgs e)
{
var browserWindow = new WebWindow();
browserWindow.ShowFromHtml(@"<html><head><title>Test title</title></head><body><p>Testsdfsdfsdfsdfdsfdsfklsdkflkdlf<br>dsfdsfdsfdsfsdfdsfds</p></body></html>");
}
}
You can also check out the code from my git repo that does something similar. KioskBrowser (GitHub)
I had the same problem. Using the CoreWebView2InitializationCompleted event handler solved it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With