CefSharp 3 and SetZoomLevel
Asked Answered
S

3

8



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.

Subroutine answered 23/5, 2016 at 10:45 Comment(3)
You'll need to specify the exact version your using, like 49.0.0 or 47.0.4. The FrameLoadEnd event is fired on ` CEF` thread, you'll have to dispatch it onto the UI thread to access a dependency property. Better to call SetZoomLevel. Remember CefSharp isn't some magic black box, the source is there, just make sure you select the correct branch that corresponds to the version your using.Alteration
I am using 49.0.0.0 and um... hm... yeah... with a simple ` private void MyBrowserOnFrameLoadEnd(object sender, FrameLoadEndEventArgs frameLoadEndEventArgs) { ChromiumWebBrowser browser = (ChromiumWebBrowser) sender; Dispatcher.Invoke(() => { browser.ZoomLevel = (Convert.ToDouble(browser.Tag) - 100) / 25.0; }); }` it works fineHarijan
If you need to set the zoom level earlier then you'll likely have to extend ChromiumWebBrowser and override OnIsBrowserInitializedChanged github.com/cefsharp/CefSharp/blob/cefsharp/49/CefSharp.Wpf/…Alteration
S
7

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.

Subroutine answered 24/5, 2016 at 6:36 Comment(4)
The WPF version has build in commands that you can just bind to for increasing, decreasing and resetting zoom. github.com/cefsharp/CefSharp/blob/cefsharp/49/CefSharp.Wpf/… github.com/cefsharp/CefSharp/blob/cefsharp/49/CefSharp.Wpf/…Alteration
Your previous.IsComplete check is also incorrect, should be if (previous.Status == TaskStatus.RanToCompletion).Alteration
You're right, but I disposed the whole idea of using a zoom and instead use a rendertransform.Harijan
Just providing alternatives for anyone else who comes across this answer.Alteration
O
0

I subclassed the browser and overrid {{OnIsBrowserInitializedChanged}}, I'm sure just subscribing would also work.

Omnipotence answered 13/10, 2021 at 17:2 Comment(0)
P
-1

It was not working for me but i have a fix for other ppl with the same problem. I will make a new topic for this fix, it will save time. this took me 5 hours to figure out. IsLoaded check is the fix...

public async void ExecuteJavaScript(string script)
    {
        if (browser != null)
            if (browser.CanExecuteJavascriptInMainFrame)
            {
                System.Windows.Forms.MessageBox.Show(browser.IsLoaded.ToString());
                if(browser.IsLoaded == true)
                browser.ExecuteScriptAsync(script);
            }
                await Task.Delay(5000);
    }
Prudery answered 11/1, 2020 at 12:59 Comment(1)
Doesn't address the problem detailed in the question, zooming only while the browser is loading isn't going to work well at all. The error might be the same, your answer is about executing JavaScript which is totally different.Alteration

© 2022 - 2024 — McMap. All rights reserved.