CefSharp 3 and SetZoomLevel

Marcel Grüger picture Marcel Grüger · May 23, 2016 · Viewed 9.6k times · Source



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.

Answer

Marcel Grüger picture Marcel Grüger · May 24, 2016

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.