最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c# - СhromiumWebBrowser scaling issue when resizing application window in WPF Application - Stack Overflow

programmeradmin1浏览0评论

I want to scale the browser window in my application to fit the available space. However, standard methods for implementing this functionality do not work correctly, as seen in the image below.

I have made some progress in attempting to fix this behavior, but the problem still occurs intermittently.

Here is how I am trying to fix it currently:

C# Code:

try
{
    _layoutUpdateCts.Cancel();
    _layoutUpdateCts = new CancellationTokenSource();

    await Task.Delay(100, _layoutUpdateCts.Token);

    // Perform size update in the UI thread
    await Dispatcher.InvokeAsync(() =>
    {
        if (chromiumWebBrowser.IsBrowserInitialized)
        {
            chromiumWebBrowser.Width = ContentGrid.ActualWidth;
            chromiumWebBrowser.Height = BrowserRow.ActualHeight;
            // Force CEF update
            chromiumWebBrowser.GetBrowser().GetHost().WasResized();
        }
    }, DispatcherPriority.Background);
}
catch (TaskCanceledException)
{
    // Ignore cancellation of previous tasks
}

XAML Code:

<CefSharp:ChromiumWebBrowser
    x:Name="chromiumWebBrowser"
    FrameLoadEnd="chromiumWebBrowser_FrameLoadEnd"
    Grid.Row="1"
    Visibility="Hidden"
    LoadingStateChanged="chromiumWebBrowser_LoadingStateChanged"
    KeyDown="Browser_KeyDown"
    MinWidth="330"
    MinHeight="250"/>

I want to scale the browser window in my application to fit the available space. However, standard methods for implementing this functionality do not work correctly, as seen in the image below.

I have made some progress in attempting to fix this behavior, but the problem still occurs intermittently.

Here is how I am trying to fix it currently:

C# Code:

try
{
    _layoutUpdateCts.Cancel();
    _layoutUpdateCts = new CancellationTokenSource();

    await Task.Delay(100, _layoutUpdateCts.Token);

    // Perform size update in the UI thread
    await Dispatcher.InvokeAsync(() =>
    {
        if (chromiumWebBrowser.IsBrowserInitialized)
        {
            chromiumWebBrowser.Width = ContentGrid.ActualWidth;
            chromiumWebBrowser.Height = BrowserRow.ActualHeight;
            // Force CEF update
            chromiumWebBrowser.GetBrowser().GetHost().WasResized();
        }
    }, DispatcherPriority.Background);
}
catch (TaskCanceledException)
{
    // Ignore cancellation of previous tasks
}

XAML Code:

<CefSharp:ChromiumWebBrowser
    x:Name="chromiumWebBrowser"
    FrameLoadEnd="chromiumWebBrowser_FrameLoadEnd"
    Grid.Row="1"
    Visibility="Hidden"
    LoadingStateChanged="chromiumWebBrowser_LoadingStateChanged"
    KeyDown="Browser_KeyDown"
    MinWidth="330"
    MinHeight="250"/>
Share Improve this question edited Mar 18 at 23:58 Stelio Kontos 6926 silver badges23 bronze badges asked Mar 18 at 23:11 ArsGeekArsGeek 112 bronze badges 2
  • re chromiumWebBrowser_LoadingStateChanged, are you checking IsLoading to ensure you're not resizing it prematurely? Also, what happens when you force a rerender after resizing? browser = chromiumWebBrowser.GetBrowser().GetHost(); browser.Invalidate(PaintElementType.View); browser.WasResized() – Stelio Kontos Commented Mar 19 at 0:40
  • There is an upstream bug at the moment with resizing. github/chromiumembedded/cef/issues/3826 – amaitland Commented Mar 22 at 23:13
Add a comment  | 

2 Answers 2

Reset to default 1

Here's an improved implementation:

// In your initialization code
public void InitializeBrowser()
{
    // Set initial size
    chromiumWebBrowser.Width = ContentGrid.ActualWidth;
    chromiumWebBrowser.Height = BrawserRow.ActualHeight;
    
    // Subscribe to parent container's size changes
    ContentGrid.SizeChanged += (sender, e) => UpdateBrowserSize();
    BrawserRow.SizeChanged += (sender, e) => UpdateBrowserSize();
    
    // For window resize events
    if (Window.GetWindow(this) is Window parentWindow)
    {
        parentWindow.SizeChanged += (sender, e) => UpdateBrowserSize();
    }
}

private CancellationTokenSource _layoutUpdateCts;

private async void UpdateBrowserSize()
{
    try
    {
        // Cancel any pending resize operations
        _layoutUpdateCts?.Cancel();
        _layoutUpdateCts = new CancellationTokenSource();
        
        // Give the layout system time to calculate new sizes
        await Task.Delay(150, _layoutUpdateCts.Token);
        
        // Ensure we're on the UI thread
        await Dispatcher.InvokeAsync(() =>
        {
            if (chromiumWebBrowser.IsBrowserInitialized)
            {
                // Apply new dimensions
                chromiumWebBrowser.Width = ContentGrid.ActualWidth;
                chromiumWebBrowser.Height = BrawserRow.ActualHeight;
                
                // Force CEF to acknowledge resize
                chromiumWebBrowser.GetBrowser()?.GetHost()?.WasResized();
                
                // Invalidate layout
                chromiumWebBrowser.InvalidateMeasure();
                chromiumWebBrowser.InvalidateVisual();
            }
        }, DispatcherPriority.Render);
    }
    catch (TaskCanceledException)
    {
        // Ignore cancellation of previous resize tasks
    }
}

Also, for your XAML, make sure your browser control is properly set up to resize:

<CefSharp:ChromiumWebBrowser x:Name="chromiumWebBrowser" 
                            FrameLoadEnd="chromiumWebBrowser_FrameLoadEnd"
                            HorizontalAlignment="Stretch"
                            VerticalAlignment="Stretch"/>

+ You can use DispatcherPriority.Render instead of Background for more responsive updates.

As a result, I use the LayoutUpdated method and in it the command:

if (chromiumWebBrowser.IsBrowserInitialized)
{
    chromiumWebBrowser.GetBrowser().GetHost().Invalidate(PaintElementType.View);
}

This gives the best result and the browser is resized correctly.

发布评论

评论列表(0)

  1. 暂无评论