Search code examples
c#wpfchromium-embeddedcefsharp

CefSharp 3 and SetZoomLevel




I am creating many ChromiumWebBrowser-Instances programmatically inside my app. On some time later I set the visibility and an address for the browser. Also I wanted to change the zoom-level. But whenever I try to change it in the normal way (like with a simple

browser.ZoomLevel = (Convert.ToDouble(browser.Tag) - 100) / 25.0;

I only get an error :IBrowser instance is null. Browser has likely not finished initializing or is in the process of disposing. But when I can set the Address, why cant I set the ZoomLevel?
Even if I try to put a method in the FrameLoadEnd and change the ZoomLevel there, I only get an error, that its on another thread. Shouldn't the event been fired on the same thread? I cannot access the sender of the event inside the event? strange...

Has someone an idea how I can change the ZoomLevel programmatically? I have to change it on load of the site and later by button.

Oh, and btw. I am using the wpf-version of CefSharp 3.


Solution

  • Ok, for everyone who wants to know the working answer here it is:

    On creation I added an eventhandler

    myBrowser.FrameLoadEnd += MyBrowserOnFrameLoadEnd;
    

    That looks like this

    private void MyBrowserOnFrameLoadEnd(object sender, FrameLoadEndEventArgs frameLoadEndEventArgs)
    {
        ChromiumWebBrowser browser = (ChromiumWebBrowser) sender;
        Dispatcher.Invoke(() =>
        {
            ZoomLevelTextBox.Text = ((Convert.ToDouble(browser.Tag) - 100) / 25.0).ToString(CultureInfo.CurrentCulture);
            browser.SetZoomLevel((Convert.ToDouble(browser.Tag) - 100) / 25.0);
        });
    }
    

    And later you can change that with two buttons

    private void IncreaseZoomOnPreview_OnClick(object sender, RoutedEventArgs e)
    {
        if (_selectedPreview < 0 || _previewItems[_selectedPreview] == null)
            return;
        ChangeZoom(0.5); //You could also use 0.1 or 1.0, as you like and in the decrease button you use -0.5, etc.
    }
    

    And the final answer to the dispatching/tasking and so on

    private void ChangeZoom(double change)
    {
        PreviewItem previewItem = _previewItems[_selectedPreview];
        ChromiumWebBrowser browser = new ChromiumWebBrowser();
        foreach (object child in ((Canvas)previewItem.PreviewBorder.Child).Children)
        {
            browser = child as ChromiumWebBrowser;
            if (browser != null)
                break;
        }
        Task<double> task = browser.GetZoomLevelAsync();
        task.ContinueWith(previous =>
        {
            if (previous.IsCompleted)
            {
                double currentLevel = previous.Result;
                browser.SetZoomLevel(currentLevel + change);
            }
            else
            {
                throw new InvalidOperationException("Unexpected failure of calling CEF->GetZoomLevelAsync", previous.Exception);
            }
        }, TaskContinuationOptions.ExecuteSynchronously);
        ZoomLevelTextBox.Text = (Convert.ToDouble(ZoomLevelTextBox.Text) + change).ToString(CultureInfo.CurrentCulture);
    }
    

    The maximum is a value of -10 to 10. So you should ask for that on a click also or set the values in a ListBox or ComboBox, etc.