Hi there,
I'm currently taking the Docking/MDI for WPF control for a test run and I really liked the BrowserUI example. NowI was a little naughty and edited the sample code to replace the old IE engine with WebView2 and got it all working (code below for those interested in what I did).
Now I am trying to basicly pick up the code and port it over to the real project and I am running into some trouble. It seens that it is using some sort of "sampleBrowser:ProductItemControl" tag and I am having trouble working out what to do with it.
Is there any like decent guidence on what to do with tags such as sampleBrowser:ProductItemControl?
Cheers
MainControl.cs
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using ActiproSoftware.Windows.Controls.Docking;
using System;
using Microsoft.Web.WebView2.Wpf;
using Microsoft.Web.WebView2.Core;
using System.IO;
using System.Collections.Generic;
namespace ActiproSoftware.ProductSamples.DockingSamples.QuickStart.BrowserUI {
/// <summary>
/// Provides the main user control for this sample.
/// </summary>
public partial class MainControl {
private int browserIndex = 0;
/////////////////////////////////////////////////////////////////////////////////////////////////////
// OBJECT
/////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>
/// Initializes an instance of the <c>MainControl</c> class.
/// </summary>
public MainControl() {
InitializeComponent();
this.AddTab("http://www.bing.com");
}
public static class Globals
{
public static readonly String APP_FOLDER_NAME = "your app folder name"; // Unmodifiable
public static readonly String URI_SCHEMA = "ms-mobile-apps:///providers/Microsoft.PowerApps/apps/";
public static readonly String APP_REQUEST_LANG = "en-AU";
public static readonly String USER_DATA_FOLDER = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), APP_FOLDER_NAME);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
// NON-PUBLIC PROCEDURES
/////////////////////////////////////////////////////////////////////////////////////////////////////
private void AddTab(string url)
{
CreateBrowserWindow(new Uri(url));
}
/// <summary>
/// Creates a new web browser <see cref="DocumentWindow"/>.
/// </summary>
/// <param name="url">The URL to load.</param>
/// <returns>The <see cref="DocumentWindow"/> that was created.</returns>
private DocumentWindow CreateBrowserWindow(Uri url) {
var options = new CoreWebView2EnvironmentOptions
{
AllowSingleSignOnUsingOSPrimaryAccount = true,
Language = $"{Globals.APP_REQUEST_LANG}"
};
var userDataFolder = System.IO.Path.Combine(Globals.USER_DATA_FOLDER);
if (!Directory.Exists(Globals.USER_DATA_FOLDER))
{
Directory.CreateDirectory(Globals.USER_DATA_FOLDER);
}
var webView2Environment = CoreWebView2Environment.CreateAsync(null, userDataFolder, options).Result;
//create new instance setting userDataFolder
WebView2 browser = new WebView2();
browser.EnsureCoreWebView2Async(webView2Environment);
browser.CoreWebView2InitializationCompleted += WebView2_CoreWebView2InitializationCompleted;
InteropFocusTracking.SetIsEnabled(browser, true);
// Create the document
var documentWindow = new DocumentWindow(dockSite, "Browser" + (++browserIndex), "New Tab", null, browser);
// Activate the document
documentWindow.Activate();
// Navigate to a page
browser.Source = url;
return documentWindow;
}
private void WebView2_CoreWebView2InitializationCompleted(object sender, CoreWebView2InitializationCompletedEventArgs e)
{
if (sender != null)
{
WebView2 wv = (WebView2)sender;
wv.CoreWebView2.Settings.AreDefaultContextMenusEnabled = true;
wv.CoreWebView2.Settings.AreDevToolsEnabled = false;
wv.CoreWebView2.Settings.IsStatusBarEnabled = false;
wv.CoreWebView2.Settings.AreBrowserAcceleratorKeysEnabled = false;
wv.CoreWebView2.Settings.AreHostObjectsAllowed = false;
wv.CoreWebView2.Settings.IsWebMessageEnabled = false;
wv.CoreWebView2.Settings.AreDefaultScriptDialogsEnabled = false;
wv.CoreWebView2.Settings.IsGeneralAutofillEnabled = false;
wv.CoreWebView2.Settings.IsPasswordAutosaveEnabled = false;
wv.CoreWebView2.NewWindowRequested += CoreWebView2_NewWindowRequested;
wv.CoreWebView2.ContextMenuRequested += menurequested;
}
}
/// <summary>
/// Occurs when the browser completes page loading.
/// </summary>
/// <param name="sender">The sender of the event.</param>
/// <param name="e">The <c>NavigationEventArgs</c> that contained data related to this event.</param>
private void OnBrowserLoadCompleted(object sender, NavigationEventArgs e) {
var browser = (WebView2)sender;
//this.UpdateUrlAndTitle(browser);
}
/// <summary>
/// Occurs when the browser starts navigation.
/// </summary>
/// <param name="sender">The sender of the event.</param>
/// <param name="e">The <c>NavigationEventArgs</c> that contained data related to this event.</param>
private void OnBrowserNavigated(object sender, NavigationEventArgs e) {
var browser = (WebView2)sender;
//this.UpdateUrlAndTitle(browser);
}
/// <summary>
/// Occurs when a new window is requested by the user.
/// </summary>
/// <param name="sender">The sender of the event.</param>
/// <param name="e">The <c>RoutedEventArgs</c> that contained data related to this event.</param>
private void OnDockSiteNewWindowRequested(object sender, RoutedEventArgs e) {
this.AddTab("Https://google.com");
}
/// <summary>
/// Occurs when a docking window is activated.
/// </summary>
/// <param name="sender">The sender of the event.</param>
/// <param name="e">The <c>DockingWindowEventArgs</c> that contains data related to this event.</param>
private void OnDockSiteWindowActivated(object sender, DockingWindowEventArgs e) {
var browser = (e.Window != null ? e.Window.Content as WebView2 : null);
if (browser != null) ;
// this.UpdateUrlAndTitle(browser);
}
/// <summary>
/// Occurs when a docking window is registered.
/// </summary>
/// <param name="sender">The sender of the event.</param>
/// <param name="e">The <c>DockingWindowEventArgs</c> that contains data related to this event.</param>
private void OnDockSiteWindowRegistered(object sender, DockingWindowEventArgs e) {
var browser = (WebView2)e.Window.Content;
//browser.LoadCompleted += OnBrowserLoadCompleted;
//browser.Navigated += OnBrowserNavigated;
}
/// <summary>
/// Occurs when a docking window is registered.
/// </summary>
/// <param name="sender">The sender of the event.</param>
/// <param name="e">The <c>DockingWindowEventArgs</c> that contains data related to this event.</param>
private void OnDockSiteWindowUnregistered(object sender, DockingWindowEventArgs e) {
var browser = (WebView2)e.Window.Content;
// browser.LoadCompleted -= OnBrowserLoadCompleted;
// browser.Navigated -= OnBrowserNavigated;
// Ensure there is always at least one browser tab
if (dockSite.DocumentWindows.Count == 0)
this.AddTab("about:blank");
}
/// <summary>
/// Updates the URL and title from the specified web browser.
/// </summary>
/// <param name="browser">The <see cref="WebBrowser"/> to examine.</param>
private void UpdateUrlAndTitle(WebBrowser browser) {
try {
// urlTextBox.Text = (browser.Source != null ? browser.Source.ToString() : string.Empty);
// var window = (DocumentWindow)browser.Parent;
// window.Title = urlTextBox.Text;
// window.FileName = urlTextBox.Text;
}
catch {}
}
private void menurequested(object sender, CoreWebView2ContextMenuRequestedEventArgs args)
{
IList<CoreWebView2ContextMenuItem> menuList = args.MenuItems;
CoreWebView2ContextMenuTargetKind context = args.ContextMenuTarget.Kind;
if (context == CoreWebView2ContextMenuTargetKind.Audio)
{
for (int index = menuList.Count - 1; index >= 0; index--)
{
menuList.RemoveAt(index);
}
}
if (context == CoreWebView2ContextMenuTargetKind.Image)
{
for (int index = menuList.Count - 1; index >= 0; index--)
{
menuList.RemoveAt(index);
}
}
if (context == CoreWebView2ContextMenuTargetKind.Page)
{
for (int index = menuList.Count - 1; index >= 0; index--)
{
if (menuList[index].Name != "reload") { menuList.RemoveAt(index); }
}
}
if (context == CoreWebView2ContextMenuTargetKind.SelectedText)
{
for (int index = menuList.Count - 1; index >= 0; index--)
{
if (menuList[index].Name != "copy" && menuList[index].Name != "paste" && menuList[index].Name != "cut") { menuList.RemoveAt(index); }
}
}
if (context == CoreWebView2ContextMenuTargetKind.Video)
{
for (int index = menuList.Count - 1; index >= 0; index--)
{
menuList.RemoveAt(index);
}
}
}
private void CoreWebView2_NewWindowRequested(object sender, Microsoft.Web.WebView2.Core.CoreWebView2NewWindowRequestedEventArgs e)
{
//WebView2 wv = (WebView2)_webView2Tabs[SelectedIndex].Content;
if (e.Uri.Contains("apps.powerapps.com/play/e/"))
{
e.NewWindow = (CoreWebView2)sender;
e.Handled = true;
}
else if (e.Uri.Contains("edge://gpu"))
{
e.NewWindow = (CoreWebView2)sender;
e.Handled = true;
}
else
{
AddTab(e.Uri);
e.Handled = true;
}
}
}
}
MainControl.xaml
<sampleBrowser:ProductItemControl
x:Class="ActiproSoftware.ProductSamples.DockingSamples.QuickStart.BrowserUI.MainControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:docking="http://schemas.actiprosoftware.com/winfx/xaml/docking"
xmlns:sampleBrowser="clr-namespace:ActiproSoftware.SampleBrowser"
>
<sampleBrowser:ProductItemControl.Resources>
<Style x:Key="BrowserTabControlStyle" TargetType="docking:AdvancedTabControl">
<Setter Property="TabBackground" Value="#e0e0e0" />
<Setter Property="TabBackgroundActiveSelected" Value="#ffffff" />
<Setter Property="TabBackgroundInactiveSelected" Value="#ffffff" />
<Setter Property="TabBackgroundPointerOver" Value="#ebebeb" />
<Setter Property="TabBackgroundPreview" Value="#e0e0e0" />
<Setter Property="TabBackgroundPreviewActiveSelected" Value="#ffffff" />
<Setter Property="TabBackgroundPreviewPointerOver" Value="#ebebeb" />
<Setter Property="TabBorderBrush" Value="#9f9f9f" />
<Setter Property="TabBorderBrushActiveSelected" Value="#9f9f9f" />
<Setter Property="TabBorderBrushInactiveSelected" Value="#9f9f9f" />
<Setter Property="TabBorderBrushPointerOver" Value="#ababab" />
<Setter Property="TabBorderBrushPreview" Value="#9f9f9f" />
<Setter Property="TabBorderBrushPreviewActiveSelected" Value="#9f9f9f" />
<Setter Property="TabBorderBrushPreviewPointerOver" Value="#ababab" />
<Setter Property="TabForeground" Value="#616161" />
<Setter Property="TabForegroundActiveSelected" Value="#000000" />
<Setter Property="TabForegroundInactiveSelected" Value="#000000" />
<Setter Property="TabForegroundPointerOver" Value="#616161" />
<Setter Property="TabForegroundPreview" Value="#000000" />
<Setter Property="TabForegroundPreviewPointerOver" Value="#616161" />
<Setter Property="TabForegroundPreviewActiveSelected" Value="#000000" />
<Setter Property="AreTabEmbeddedButtonsAlwaysVisible" Value="True" />
<Setter Property="Background" Value="#ffffff" />
<Setter Property="BorderBrush" Value="#9f9f9f" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="CanTabsCloseOnMiddleClick" Value="True" />
<Setter Property="CanTabsDrag" Value="True" />
<Setter Property="HasNewTabButton" Value="True" />
<Setter Property="HasTabCloseButtons" Value="True" />
<Setter Property="HighlightThickness" Value="0" />
<Setter Property="TabCornerRadius" Value="2" />
<Setter Property="TabNearSlantExtent" Value="8" />
<Setter Property="TabFarSlantExtent" Value="8" />
<Setter Property="TabPadding" Value="5,4" />
<Setter Property="TabSpacing" Value="-10" />
<Setter Property="NewTabButtonStyle">
<Setter.Value>
<Style TargetType="docking:NewTabButton">
<Setter Property="Background" Value="#e0e0e0" />
<Setter Property="BorderBrush" Value="#9f9f9f" />
<Setter Property="Margin" Value="6,4,0,0" />
<Setter Property="Width" Value="32" />
<Setter Property="Height" Value="16" />
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="docking:NewTabButton">
<Path Fill="{TemplateBinding Background}" Stroke="{TemplateBinding BorderBrush}"
Data="M 0.5,1.5 Q 0.5,0.5 1.5,0.5 L 23.5,0.5 Q 27.5,0.5 31.5,14.5 Q 31.5,15.5 30.5,15.5 L 8.5,15.5 Q 4.5,15.5 0.5,1.5 Z" />
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#ebebeb" />
<Setter Property="BorderBrush" Value="#ababab" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="docking:TabbedMdiContainer">
<Setter Property="MinTabExtent" Value="200" />
<Setter Property="MaxTabExtent" Value="200" />
</Style>
</sampleBrowser:ProductItemControl.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<!-- DockSite -->
<docking:DockSite x:Name="dockSite" Grid.Row="1" Grid.ColumnSpan="2"
AreNewTabsInsertedBeforeExistingTabs="False"
UseHostedPopups="False"
NewWindowRequested="OnDockSiteNewWindowRequested"
WindowActivated="OnDockSiteWindowActivated"
WindowRegistered="OnDockSiteWindowRegistered"
WindowUnregistered="OnDockSiteWindowUnregistered"
>
<docking:DockSite.Switcher>
<docking:StandardSwitcher AreToolWindowsVisible="False" />
</docking:DockSite.Switcher>
<!-- Workspace -->
<docking:Workspace>
<docking:TabbedMdiHost x:Name="tabbedMdiHost" TabControlStyle="{StaticResource BrowserTabControlStyle}" ContainersHaveNewTabButtons="True" TabOverflowBehavior="Shrink" />
</docking:Workspace>
</docking:DockSite>
</Grid>
</sampleBrowser:ProductItemControl>