namespace VideoBrowser.Controls.CefSharpBrowser { using CefSharp; using CefSharp.Wpf; using System.Windows; using System.Windows.Input; using VideoBrowser.Common; using VideoBrowser.Controls.CefSharpBrowser.Handlers; using VideoBrowser.Controls.CefSharpBrowser.Helpers; using VideoBrowser.Helpers; /// /// Interaction logic for CefSharpBrowser.xaml. /// public partial class CefSharpBrowser { #region Fields public static readonly DependencyProperty BackwardCommandProperty = DependencyProperty.Register(nameof(BackwardCommand), typeof(ICommand), typeof(CefSharpBrowser), new PropertyMetadata(null)); public static readonly DependencyProperty ForwardCommandProperty = DependencyProperty.Register(nameof(ForwardCommand), typeof(ICommand), typeof(CefSharpBrowser), new PropertyMetadata(null)); public static readonly DependencyProperty IsAirspaceVisibleProperty = DependencyProperty.Register(nameof(IsAirspaceVisible), typeof(bool), typeof(CefSharpBrowser), new PropertyMetadata(false)); public static readonly DependencyProperty IsFullScreenCommandProperty = DependencyProperty.Register(nameof(IsFullScreenCommand), typeof(ICommand), typeof(CefSharpBrowser), new PropertyMetadata(null, OnIsFullScreenCommandChanged)); public static readonly DependencyProperty ReloadCommandProperty = DependencyProperty.Register(nameof(ReloadCommand), typeof(ICommand), typeof(CefSharpBrowser), new PropertyMetadata(null)); public static readonly DependencyProperty TitleProperty = DependencyProperty.Register(nameof(Title), typeof(string), typeof(CefSharpBrowser), new FrameworkPropertyMetadata("Home", FrameworkPropertyMetadataOptions.BindsTwoWayByDefault)); public static readonly DependencyProperty UrlProperty = DependencyProperty.Register(nameof(Url), typeof(string), typeof(CefSharpBrowser), new FrameworkPropertyMetadata(string.Empty, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnUrlChanged)); public static readonly DependencyProperty WebBrowserProperty = DependencyProperty.Register(nameof(WebBrowser), typeof(IWebBrowser), typeof(CefSharpBrowser), new PropertyMetadata(null)); #endregion Fields #region Constructors /// /// Initializes a new instance of the class. /// public CefSharpBrowser() { Initialize(); this.CefDisplayHandler = new CefDisplayHandler(); this.InitializeComponent(); this.ChromiumWebBrowser.TitleChanged += this.OnChromiumWebBrowser_TitleChanged; this.Loaded += this.OnLoaded; } #endregion Constructors #region Properties /// /// Gets or sets the BackwardCommand. /// public ICommand BackwardCommand { get { return (ICommand)GetValue(BackwardCommandProperty); } set { SetValue(BackwardCommandProperty, value); } } /// /// Gets the CefSettings. /// public CefSettings CefSettings { get; } /// /// Gets or sets the ForwardCommand. /// public ICommand ForwardCommand { get { return (ICommand)GetValue(ForwardCommandProperty); } set { SetValue(ForwardCommandProperty, value); } } /// /// Gets or sets a value indicating whether IsAirspaceVisible. /// public bool IsAirspaceVisible { get { return (bool)GetValue(IsAirspaceVisibleProperty); } set { SetValue(IsAirspaceVisibleProperty, value); } } /// /// Gets or sets the IsFullScreenCommand. /// public ICommand IsFullScreenCommand { get { return (ICommand)GetValue(IsFullScreenCommandProperty); } set { SetValue(IsFullScreenCommandProperty, value); } } /// /// Gets or sets the ReloadCommand. /// public ICommand ReloadCommand { get { return (ICommand)GetValue(ReloadCommandProperty); } set { SetValue(ReloadCommandProperty, value); } } /// /// Gets or sets the Title. /// public string Title { get { return (string)GetValue(TitleProperty); } set { SetValue(TitleProperty, value); } } /// /// Gets or sets the Url. /// public string Url { get { return (string)GetValue(UrlProperty); } set { SetValue(UrlProperty, value); } } /// /// Gets or sets the WebBrowser. /// public IWebBrowser WebBrowser { get { return (IWebBrowser)this.GetValue(WebBrowserProperty); } set { this.SetValue(WebBrowserProperty, value); } } /// /// Gets or sets a value indicating whether CanBackward. /// private bool CanBackward { get; set; } /// /// Gets or sets a value indicating whether CanForward. /// private bool CanForward { get; set; } /// /// Gets or sets a value indicating whether CanReload. /// private bool CanReload { get; set; } /// /// Gets the CefDisplayHandler. /// private CefDisplayHandler CefDisplayHandler { get; } #endregion Properties #region Methods /// /// The Initialize. /// public static void Initialize() { if (!Cef.IsInitialized) { System.AppContext.SetSwitch("Switch.System.Windows.Input.Stylus.EnablePointerSupport", true); const bool multiThreadedMessageLoop = true; var browserProcessHandler = new BrowserProcessHandler(); var settings = new CefSettings { //UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:68.0) Gecko/20100101 Firefox/68.0", MultiThreadedMessageLoop = multiThreadedMessageLoop, ExternalMessagePump = !multiThreadedMessageLoop }; settings.PersistSessionCookies = true; settings.SetOffScreenRenderingBestPerformanceArgs(); settings.CefCommandLineArgs.Remove("disable-gpu-compositing"); CefConfig.Init(settings, browserProcessHandler: browserProcessHandler); } } /// /// The OnIsFullScreenCommandChanged. /// /// The d. /// The e. private static void OnIsFullScreenCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var browser = (CefSharpBrowser)d; var isFullScreenCommand = (ICommand)e.NewValue; browser.CefDisplayHandler.IsFullScreenCommand = isFullScreenCommand; } /// /// The OnUrlChanged. /// /// The d. /// The e. private static void OnUrlChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { UIThreadHelper.InvokeAsync(() => { CommandManager.InvalidateRequerySuggested(); }); } /// /// The OnBackward. /// /// The obj. private void OnBackward(object obj) { if (this.WebBrowser.CanGoBack) { this.WebBrowser.Back(); } } /// /// The OnChromiumWebBrowser_TitleChanged. /// /// The sender. /// The e. private void OnChromiumWebBrowser_TitleChanged(object sender, DependencyPropertyChangedEventArgs e) { UIThreadHelper.InvokeAsync(() => this.Title = (string)e.NewValue); } /// /// The OnForward. /// /// The obj. private void OnForward(object obj) { if (this.WebBrowser.CanGoForward) { this.WebBrowser.Forward(); } } /// /// The OnLoaded. /// /// The sender. /// The e. private void OnLoaded(object sender, RoutedEventArgs e) { this.Loaded -= this.OnLoaded; this.WebBrowser = this.ChromiumWebBrowser; this.WebBrowser.LoadingStateChanged += OnWebBrowser_LoadingStateChanged; this.WebBrowser.LoadError += OnWebBrowser_LoadError; this.WebBrowser.DisplayHandler = this.CefDisplayHandler; this.WebBrowser.KeyboardHandler = new CefKeyboardHandler(this.ChromiumWebBrowser); this.BackwardCommand = new RelayCommand(this.OnBackward, "Backward", (o) => this.CanBackward); this.ForwardCommand = new RelayCommand(this.OnForward, "Forward", (o) => this.CanForward); this.ReloadCommand = new RelayCommand(this.OnReload, "Reload", (o) => this.CanReload); } /// /// The OnReload. /// /// The obj. private void OnReload(object obj) { this.WebBrowser.Reload(true); } /// /// The OnWebBrowser_LoadError. /// /// The sender. /// The e. private void OnWebBrowser_LoadError(object sender, LoadErrorEventArgs e) { } /// /// The OnWebBrowser_LoadingStateChanged. /// /// The sender. /// The e. private void OnWebBrowser_LoadingStateChanged(object sender, LoadingStateChangedEventArgs e) { UIThreadHelper.Invoke(() => { this.CanBackward = e.CanGoBack; this.CanForward = e.CanGoForward; this.CanReload = e.CanReload; }); } #endregion Methods } }