The Chromium based WebView2 Control SDK is now Generally Available (GA). It enables Web technologies (HTML...) in native applications. We explore the possibilities of this control to browse folders and display several animated image formats such as Gif, Png, WebP, video WebM, Mp4 and Mp3 audio. From two sample programs, we create a C# WPF .NET5.0 program and add some local folder and file support. A very global description of the scenarios supported, its Basic UI and creation of the program are given.
Introduction
The status of the WebView2
Control has changed from preview to Generally Available (GA). "The Microsoft Edge WebView2
control enables you to embed web technologies (HTML... ) in native applications. It uses Microsoft Edge (Chromium) as the rendering engine to display web content ...". See here for the pitch for a hybrid native/web app approach.
In the past, I made a variant of my ImageWallViewer for displaying Gifs. I played for fun with some options for displaying gifs (MediaPlayer
, a WinForms viewbox or so, an XAML Island with a UWP image, etc.). For this purpose, I liked WpfAnimatedGif the best.
However, there are other types like for example, animated .Png, .Webp and .Webm formats. I noticed that when I dropped files on the Edge addressbar, they are displayed fine while not all image viewers handle all these types .
I did not test a webbrowser
control to display animated .Gif and other formats, so I decided to do some trial and error hacking to test the potential use of WebView2
to browse through folders and display animated .Gif, .Png, .WebM, .WebP, .Mp4 etc.
In several steps, I implemented provisory three basic scenarios:
- Get a folder using a
FolderDialog
and browse trough the files in the folder using Previous and Next File. - Drop a file or folder from File Explorer on the
WebView2
Control itself or navigate with the Control
using the current Folder view. - Use Back and Forward URL using the capabilities of
WebView2
.
I took two sample projects and added some folder and file support. I also added two proofs of concept. One is the generation of a .HTML file with three columns of all (animated) images in a folder, the other is to start the next .Mp3 audio file after the current has ended.
In the next sections, we will discuss:
- Prerequisites, use Evergreen
- The basic UI of the program
- Basic building of a C# WPF .NetCore application with a
WebView2
Control - Adding Native Folders and File handling,
ViewModel
- Displayed and Allowed local file types
- Play next .mp3 audio file in folder
- Construct a .html page with 3 columns of animated images
- Publishing .exe file
- Points learned
Prerequisites, Use Evergreen
In the program now WebView2 SDK 1.0.664.37 is used. Release SDKs are now forward-compatible. The SDK defines the minimum version of Chromium needed to run the program. I have Edge Dev version 88.0.705.9 and this seems OK because 705.9 is higher then 644.37.
Now that .NET WPF/WinForms WebView2
is now out of Preview and Generally Available (GA), it is recommended that for distribution of apps, the WebView2
runtime is used. See for more details about downloading the Evergreen solution here. It is also possible to download Chromium by the distributed program.
I have upgraded the project to NET5.0. Now the download of Chromium is possible with Evergreen I wanted to provide an .exe. However, now, the zipped .exe files are too large (60 MB), so I could not add that to this tip/trick.
Basic UI of Program
Note in Figure 1 that when the Address of the WebView2
Control is a folder, the control shows a Folder View that can be used to browse folders and select files.
Figure 1. Basic UI of Program
Short description of the two groups at the top of the window:
- Second Group Back/Forward URL left part: Backward, Forward and URL addressbar.
- Second Group Back/Forward URL right part: Folder/files handling ("native App"). With the Folder icon button, you can select a new folder, if possible, it will display the first file in the Folder. Using Prev File in Folder and Next File buttons, you can browse through the files in the folder. The This Folder button will render the folder in the
WebView2
control (see figure 1) and then WebView2
control can be used to browse through folders (not drives) or select a file. - Folders or files can be dropped on the
WebView2
control or you can browse in the WebView2
control when a folder is rendered. If a (valid) file or folder is selected, the folder and current file are adapted, so the Prev File and Next File in folder buttons can be used. - Upper Group Test/Debug is gray but can be used. Button HtmlTest was for some experiments with events, Make All.html generates and saves a page All.html of all images/video in the folder with three columns. The folder text boxes right (Folder en Current nr) are for debugging.
The program will look for a .ini file in the same folder as the program for the start folder. If that file does not exist, it will write a .ini file, that can be edited by hand to set a folder that does exist on your system.
Basic C# WPF .NetCore Program with WebView2 Control
I followed these instructions (see the link) to create a basic C# WPF .NET Core program with a WebView2
. Easy peasy, works fine. Nothing to add to that. WPF .NET Core project has made quite a few steps in the last months. Single .exe file seemed no problem.
The last step I took was to implement the Back and Forward buttons for the browser. When I Googled, I found the example here (see the link) and copied that part of it. There are also C samples given, not studied but seems to use files.
Adding Native Folders and File Handling, ViewModel
We implemented the four buttons (see figure 1):
- Previous File in Folder
- Next File in Folder
- Show Current Folder in WebView2
- Select new Folder
I added a ViewModel
, also calls from code behind. It has Notified properties: NewAddresFromWebView
, MyAddress
, MyNewFolder
, MyFolder
, MyFiles
, Current
and Commands Prev
, Next
, ShowFolder
. MyAddress
is bound in the View
so if MyAddress
changes, the address of the WebView2
Control in the View changes.
Pressing the select new Folder button starts in code behind a FolderDialog
and sets MyNewFolder
. MyNewFolder
sets MyFolder
, MyFiles
and sets Current
to 0
. Current
sets MyAddress
to MyFiles[Current]
, so the first file is displayed in the View.
Commands Prev
(sets Current-1
) and Next
(sets Current +1
) are bound to the prev File and next File in Folder buttons. Command ShowFolder
sets MyAddress
to MyFolder
and so the current Folder is rendered in the WebView2
Control (see figure 1).
If the URLs of the WebView2
Control are changed by user input (browsing in WebView2
control, dropping File or Folder on WebView2
Control), UpdateAddressBar
is raised in code behind and sets NewAddresFromWebView
. It tries to extract and set MyFolder
, MyFiles
and current (not Current) from the reported Address. If MyFolder
is valid, no action is taken but we can now use the prev/next file in Folder
buttons to scroll to next files and folders.
Displayed and Allowed Local File Types
This experiment started because I noted that local file types like animated images like .Webp, .Webm and .Png were displayed without problems in Edge, while not all image viewers can do this. I was surprised to see that when I started browsing, local folders are displayed (see figure 1) but also .Txt, .Pdf and .Eml files. I noted also that a lot of local file types were not displayed but downloaded. Not only .Zip files but also .Wma, .Mpeg and .Avi, etc. Initially, I did think that it was a matter of settings to change this behavior. If we inspect the WebView2
rendered html page by using the context menu of a local .Mp4 video or .mp3 audio file, we see that a .Html page is generated with a <video>
element and as source the local file, a .Txt file is copied inside <pre>
elements, etc. I have not examined this thoroughly but as I understand it now, Edge excels at displaying media is supported by HTML and does this by creating an HTML webpage, and other media formats are not supported. See here for some types that are displayed by Edge.
So Edge/WebView2 seems not the ultimate rendering machine for all local file types, but does well for some Html standard supported file types. Anyhow, the downloading is annoying so I created a small list with allowable types for local files and used it to filter MyFiles. I also prevented to display/download files by canceling the URL request in the listener to NavigationStarting
(here: EnsureValidUrl
). I did not adapt the .Html page of the local FolderView
.
Play Next .mp3 Audio File in Folder
We did also take a look at how to play the next .Mp3 audio file in folder after the current audio file has ended playing. In the event listener of the NavigationStarting
event (in code below EnsureValidUrl
), we inject for local .Mp3 audio files a JavaScript, that adds an event listener to the "Ended
" event of the <video>
element that has name ="media
". This generates a postMessage
"Event:AudioEnded
" (see code below) that is handled by the P# program.
..
webView.NavigationStarting += EnsureValidUrl;
..
void EnsureValidUrl(object sender, CoreWebView2NavigationStartingEventArgs args)
{
..
if (isAudio)
{
string javaScript =
"var v = document.getElementsByName(\"media\")[0];";
javaScript = javaScript +
"v.addEventListener(\"ended\", function()
{ window.chrome.webview.postMessage(\"Event:AudioEnded\") } )";
webView.CoreWebView2.ExecuteScriptAsync(javaScript);
}
..
}
Construct .html page with Three Columns of Animated Images
As proof of concept/experiment, I added a command to construct and save an All.Html page with a table with three columns of the animated images in a folder, see code below:
public void OnMakeHtmlTable()
{
List<string> lines = new List<string>
{ "<!DOCTYPE html> <html> <head> " };
Lines.Add
(" <style> video { width: 90 %; } img { width: 90%;}
</style> </head> <body> <table >");
int nColumn = 3;
int iFile = 0;
int nFile = Vm.MyFiles.Count;
for (int iRow = 0; iFile < nFile -1; iRow++)
{
lines.Add("<tr>");
for (int iCol = 0; (iCol < nColumn) && (iFile < nFile -1); )
{
iFile++;
Model.MyFileInfo file = Vm.MyFiles[iFile];
Uri uri = new Uri(file.FullName);
string file1 = uri.AbsoluteUri;
file1 = '"' + file1 + '"';
string ext = Path.GetExtension(file.FullName).ToLower();
bool isImg = (Array.IndexOf(Vm.ExtImg, ext) >= 0);
bool isVideo = (Array.IndexOf(Vm.ExtVideo, ext) >= 0);
if ((isImg) || (isVideo))
{
iCol++;
lines.Add("<td>");
string fileNameOnly = '"' + file.Name + '"';
if (isImg) lines.Add($"<img src={file1} title={fileNameOnly} />");
if (isVideo)
lines.Add($"<video autoplay loop mute src={file1} title={fileNameOnly} />");
lines.Add("</td>");
}
}
lines.Add("</tr>");
}
lines.Add(" </table> </body> </html> ");
System.IO.File.WriteAllLines(Vm.MyFolder+"//All.html", lines);
}
Looking at the scrollbar, it takes some time to read all animated images or videos. In my tip/trip, ImageWallViewer, I only presented Image Names currently displayed according to scrollbar, that is faster. Memory and CPU wise the all.html page is handled relatively well. It suffices, but it is not responsive yet, sometimes resizing needed.
Publishing .exe File
Initially, UWP apps and the Microsoft store were promoted as the (only) way forward by Microsoft. This has been shifted by the new MSIX packaging format, developing its own package manager and recently project Reunion.
Using the VS Community 2019 Menu Build...Publish, we can publish to Azure, Docker or a Folder. I still like the good (?) old single .exe file so we publish to a Folder. Tip: In developing a small utility, you can regularly publish in a separate folder so you always have a working version at hand during development. The project file is readable XML. I have changed the project file now to Net5.0, see figure 2.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net5.0-windows</TargetFramework>
<RuntimeIdentifier>win10-x64</RuntimeIdentifier>
<PublishSingleFile>true</PublishSingleFile>
<PublishTrimmed>true</PublishTrimmed>
<PublishReadyToRun>true</PublishReadyToRun>
<UseWPF>true</UseWPF>
</PropertyGroup>
....
Figure 2. Part of Project File for net 5.0.
I tried to publish a self contained single .exe file. In the Publish profile, edit, it is possible to change the deployment mode from Framework Dependent to Self Contained. I tried this option, but that seemed not to generate a Single File. It seems that not all APIs allow to generate a single file. Now that the EverGreen option is available, I wanted to include this time an .exe but the .exe and accompanied files exceed the 10 MB constraint.
Points Learned
- For this simple case, it seems possible to mix Web technology in a Native WPF program.
- Main conclusion is that animated .Gif, .Png, .Webp and .Webm are rendered. That is a positive result. Did not compare with a recent
MediaPlayer
. In the next stage for a more specialized control, details like stretching, remove context menu, etc. are important. - A little experiment with three columns of animated images shows that Edge/WebView2 handles the display of a grid reasonable well.
- When a folder is rendered, we get a
FolderView
(see figure 1) that can be used for Browsing Folders and selecting files. This rendering is limited, it cannot be used for changing drives. WebView2
is good at rendering local file types that are supported by the HTML standard. Most file types have a default behavior. A .Zip file is downloaded but also .Wma audio or .Mpeg Video. For that reason, we applied a list of allowed file types. - The program seems also to my surprise play local
MusicFolders
, show e_mails, text documents, etc. For navigation though MusicFolders
, it could be considered to introduce buttons to next, previous and random folder with same parent. - Creating a new .NET Core WPF program is now rather straightforward, XAML editor works fine. Also, more and more NuGet packages support .NET core.
- Distribution of programs with the
WebView2
SDK is a little more complex, but the Evergreen solution makes it more easy to install the correct Chromium version.
History
- 11th June, 2020: Initial version
- 8th December, 2020: Update
WebView2
Generally Available (GA)
- Some text adapted, reflecting status
WebView2
Preview to GA - Updated to SDK Chromium 1.0.664.37, "Starting with this release, Release SDKs are forward-compatible."
- Mentioned Evergreen in Prerequisites to obtain latest version of Chromium
- Added no zip with .Exe, to big (60 MB)
- Filter with allowed type list in
MyFiles
and EnsureValidUri
/Display
- Play next local .MP3 file in folder by inserting script listening to "
Ended
" event and handle this. - Button to make/save an All.Html with table with three columns video/images
- Small modifications. Tried
DockPanel
s instead of grids, use groups, ProjectFile
updated to Net5.0