private void InitializeBrowser(ChromiumWebBrowser webBrowser) { webBrowser.RequestHandler = this; webBrowser.LifeSpanHandler = this; webBrowser.RegisterJsObject("callbackObject", this.callback); // So. Fun story. From https://github.com/cefsharp/CefSharp/issues/738#issuecomment-91099199, we need to set the zoom level // in the FrameLoadStart event. However, the IWpfWebBrowser's ZoomLevel is a DependencyProperty, and it wraps // the SetZoomLevel method on the unmanaged browser (which is exposed directly by ChromiumWebBrowser, but not by IWpfWebBrowser). // Now, FrameLoadState and FrameLoadEnd are called on a background thread, and since ZoomLevel is a DP, it can only be changed // from the UI thread (it's "helpful" and does a dispatcher check for us). But, if we dispatch back to the UI thread to call // ZoomLevel = xxx, then CEF seems to hit threading issues, and can sometimes render things entirely badly (massive icons, no // localization, bad spacing, no JavaScript at all, etc). // So, in this case, we need to call SetZoomLevel directly, as we can do that from the thread on which FrameLoadStart is called, // and everything's happy. // However, this means that the DP value isn't updated... Which means we can't use the DP at all. We have to call SetZoomLevel // *everywhere*, and that means keeping a local field zoomLevel to track the current zoom level. Such is life webBrowser.FrameLoadStart += (o, e) => webBrowser.SetZoomLevel(this.zoomLevel); webBrowser.FrameLoadEnd += (o, e) => { if (e.IsMainFrame && e.Url != "about:blank") { var script = @"$('#folders .panel-footer .pull-right').prepend(" + @"'<button class=""btn btn-sm btn-default"" onclick=""callbackObject.openFolder(angular.element(this).scope().folder.id)"">" + @"<span class=""fa fa-folder-open""></span>" + @"<span style=""margin-left: 3px"">" + Resources.ViewerView_OpenFolder + "</span></button>')"; webBrowser.ExecuteScriptAsync(script); } }; }
private void InitializeBrowser(ChromiumWebBrowser webBrowser) { webBrowser.RequestHandler = this; webBrowser.LifeSpanHandler = this; // Enable WPF touch scrolling - may cause issues, see https://github.com/cefsharp/CefSharp/pull/1418 webBrowser.IsManipulationEnabled = true; webBrowser.RegisterJsObject("callbackObject", this.callback); // So. Fun story. From https://github.com/cefsharp/CefSharp/issues/738#issuecomment-91099199, we need to set the zoom level // in the FrameLoadStart event. However, the IWpfWebBrowser's ZoomLevel is a DependencyProperty, and it wraps // the SetZoomLevel method on the unmanaged browser (which is exposed directly by ChromiumWebBrowser, but not by IWpfWebBrowser). // Now, FrameLoadState and FrameLoadEnd are called on a background thread, and since ZoomLevel is a DP, it can only be changed // from the UI thread (it's "helpful" and does a dispatcher check for us). But, if we dispatch back to the UI thread to call // ZoomLevel = xxx, then CEF seems to hit threading issues, and can sometimes render things entirely badly (massive icons, no // localization, bad spacing, no JavaScript at all, etc). // So, in this case, we need to call SetZoomLevel directly, as we can do that from the thread on which FrameLoadStart is called, // and everything's happy. // However, this means that the DP value isn't updated... Which means we can't use the DP at all. We have to call SetZoomLevel // *everywhere*, and that means keeping a local field zoomLevel to track the current zoom level. Such is life webBrowser.FrameLoadStart += (o, e) => webBrowser.SetZoomLevel(this.zoomLevel); webBrowser.FrameLoadEnd += (o, e) => { if (e.Frame.IsMain && e.Url != "about:blank") { var addOpenFolder = @"$('#folders .panel-footer .pull-right').prepend(" + @" '<button class=""btn btn-sm btn-default"" onclick=""callbackObject.openFolder(angular.element(this).scope().folder.id)"">" + @" <span class=""fa fa-folder-open""></span>" + @" <span style=""margin-left: 3px"">" + Resources.ViewerView_OpenFolder + @"</span>" + @" </button>')"; webBrowser.ExecuteScriptAsync(addOpenFolder); var addFolderBrowse = @"$('#folderPath').wrap($('<div/>').css('display', 'flex'));" + @"$('#folderPath').after(" + @" $('<button>').attr('id', 'folderPathBrowseButton')" + @" .addClass('btn btn-sm btn-default')" + @" .html('" + Resources.ViewerView_BrowseToFolder + @"')" + @" .css({'flex-grow': 1, 'margin': '0 0 0 5px'})" + @" .on('click', function() { callbackObject.browseFolderPath() })" + @");" + @"$('#folderPath').removeAttr('list');" + @"$('#directory-list').remove();" + @"$('#editFolder').on('shown.bs.modal', function() {" + @" if ($('#folderPath').is('[readonly]')) {" + @" $('#folderPathBrowseButton').attr('disabled', 'disabled');" + @" }" + @" else {" + @" $('#folderPathBrowseButton').removeAttr('disabled');" + @" }" + @"});"; webBrowser.ExecuteScriptAsync(addFolderBrowse); } }; }