webbrowser not navigating if you're not looking at it
Asked Answered
C

2

6

I got a strange problem. I have a tabcontrol and 3 tabs. On every tab i got a webbrowser control on it. They all navigate to a website. But it only navigates if you're actually looking at the webbrowser control. So having it minimized on taskbar or systray, wont make it navigate to a website.

Why is that? How can i change this behavior?

[EDIT]

This only seems to happen when i startup the app. After it got 'focus' or a 'look at', this doesn't happen anymore.

Some more info, the navigating happens from a different thread than the UI-thread. [/EDIT]

[3nd EDIT]

Here is a test case:

XAML code:

<Window x:Class="WPFWebbrowserFocusTest.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="453" Width="755">
<Grid>
    <TabControl Height="390" HorizontalAlignment="Left" Margin="12,12,0,0" Name="tabControl1" VerticalAlignment="Top" Width="709">
        <TabItem Header="tabItem1" Name="tabItem1">
            <Grid>
                <Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="18,17,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" />
            </Grid>
        </TabItem>
        <TabItem Header="tabItem2" Name="tabItem2">
            <Grid>
                <WebBrowser Height="352" HorizontalAlignment="Left" Margin="0,6,0,0" Name="webBrowser1" VerticalAlignment="Top" Width="693" Navigated="webbrowser_Navigated" LoadCompleted="webbrowser_LoadCompleted" />
            </Grid>
        </TabItem>
        <TabItem Header="tabItem3" Name="tabItem3">
            <Grid>
                <WebBrowser Height="346" HorizontalAlignment="Left" Margin="6,6,0,0" Name="webBrowser2" VerticalAlignment="Top" Width="687" Navigated="webbrowser_Navigated" LoadCompleted="webbrowser_LoadCompleted" />
            </Grid>
        </TabItem>
        <TabItem Header="tabItem4" Name="tabItem4">
            <Grid>
                <WebBrowser Height="346" HorizontalAlignment="Left" Margin="10,10,0,0" Name="webBrowser3" VerticalAlignment="Top" Width="687" Navigated="webbrowser_Navigated" LoadCompleted="webbrowser_LoadCompleted" />
            </Grid>
        </TabItem>
        <TabItem Header="tabItem5" Name="tabItem5">
            <Grid>
                <WebBrowser Height="346" HorizontalAlignment="Left" Margin="10,10,0,0" Name="webBrowser4" VerticalAlignment="Top" Width="687" Navigated="webbrowser_Navigated" LoadCompleted="webbrowser_LoadCompleted" />
            </Grid>
        </TabItem>
    </TabControl>
</Grid>

Here is the code behind file:

public MainWindow()
{
   InitializeComponent();
}

private void webbrowser_Navigated(object sender, NavigationEventArgs e)
{ 
   this.SuppressScriptErrors((WebBrowser)sender, true);
}

private void webbrowser_LoadCompleted(object sender, NavigationEventArgs e)
{
    WebBrowser wb = (WebBrowser)sender;

    if (e.Uri.AbsoluteUri != wb.Source.AbsoluteUri)
        return;
}

public void SuppressScriptErrors(System.Windows.Controls.WebBrowser wb, bool Hide)
{
    FieldInfo fi = typeof(System.Windows.Controls.WebBrowser).GetField(
            "_axIWebBrowser2", BindingFlags.Instance | BindingFlags.NonPublic);

    if (fi != null)
    {
        object browser = fi.GetValue(wb);

        if (browser != null)
        {
            browser.GetType().InvokeMember("Silent", BindingFlags.SetProperty, null, browser, new object[] { Hide });
        }
    }
}

private void button1_Click(object sender, RoutedEventArgs e)
{
    this.webBrowser1.Navigate("http://www.google.com");
    this.webBrowser2.Navigate("http://www.google.com");
    this.webBrowser3.Navigate("http://www.google.com");
    this.webBrowser4.Navigate("http://www.google.com");
}

How to reproduce:

Put a breakpoint inside webbrowser_LoadCompleted. Then press the button which is located on the first tabpage of the tabcontrol.

Dont go to the next tabpage yet, wait a coupled of seconds, like 15 or so.

Then go to tabitem2 or 3/4/5. You'll see that the page just got loaded and the webbrowser_LoadCompleted event got fired.

Clair answered 1/1, 2012 at 12:8 Comment(11)
How would it navigate if it is minimized?Nebuchadnezzar
Why isn't this an issue in winforms?Clair
This shouldn't be happening, regardless if WebBrowser control is not focused, visible or even just instantiated in memory, it should always navigate to the page. Can you post some simplified xaml code and then how are you calling these Navigate methods? @Yustme, this isn't an issue with WPF, too.Autogenesis
it's a multi-threaded application, and i'm navigating from a different thread than the UI-thread. can that be the reason why i get this behavior?Clair
See my answer below, invoking the Dispatcher might solve your problem.Autogenesis
You do not need to call dispatcher to get the textbox value. I edited your original code. However, even with this, I'm not able to reproduce the bug.Autogenesis
see my last post under your answer.Clair
Try putting the browser control in a page and the page in a frame of the tabitem. I did not do this with a Browser control but I did with a TextBlock that displays a large amount of text I got the behavior of the text only loading when the tab got focus. You have the option of binding the brower to a source in XAML, assigning in code, or passing in the constructor. A page has a life cycle that you might be able to exploit.Munitions
'try putting the browser control in a page', what is a page? it says i cant add content to frame as a compiler error msg.Clair
no one that can explain this behavior or fix it?Clair
By removing the possibility to suppress js script errors, obfuscating how to access page code and blocking navigation on invisible WebBrowsers, it seems MS deliberately contributed to reduce the number of C# bots, as the most interesting functions of WebBrowser were: To navigate anywhere without any js bug popup, to access quickly the source, and to use hidden WebBrowser for some badass illicit activities. They claimed they lacked of time when developing this WPF WebBrowser. BS. It's even worse on Windows Phone now.Hydrocele
C
0

It seems that this is the behavior of this control in WPF according to the docs.

Clair answered 27/3, 2012 at 20:23 Comment(0)
A
1

Here's a code fragment in WPF that works. Once you click the button, it minimizes the application, and after 2 seconds calls navigate to all browsers while the window is minimized. Pages are loaded in all tabs regardless of window state or tab focus. Make sure are calling Navigate inside a Dispatcher.Invoke. You can't make UI changes in WPF from a different thread unless you call the dispatcher. That might be a problem. My example below calls the navigation from a different thread.

<Window x:Class="WpfApplication3.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        DataContext="{Binding RelativeSource={RelativeSource Self}}"
        Title="MainWindow" Height="350" Width="525"
        StateChanged="Window_StateChanged">
    <Grid>
        <TabControl Height="225" HorizontalAlignment="Left" Margin="12,12,0,0" Name="tabControl1" VerticalAlignment="Top" Width="491">
            <TabItem Header="tabItem1">
                <WebBrowser Height="189" Name="webBrowser1" Width="479" />
            </TabItem>
            <TabItem Header="tabItem2">
                <WebBrowser Height="185" Name="webBrowser2" Width="466" />
            </TabItem>
            <TabItem Header="tabItem3">
                <WebBrowser Height="187" Name="webBrowser3" Width="434" />
            </TabItem>
        </TabControl>
        <Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="116,268,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" />
        <TextBox Height="23" HorizontalAlignment="Left" Margin="236,268,0,0" Name="textBox1" VerticalAlignment="Top" Width="120" />
    </Grid>
</Window>

private void button1_Click(object sender, RoutedEventArgs e)
{
    this.WindowState = System.Windows.WindowState.Minimized;
}

private void Window_StateChanged(object sender, EventArgs e)
{
    if (this.WindowState == System.Windows.WindowState.Minimized)
    {
        new Thread((state) =>
        {
            Thread.Sleep(TimeSpan.FromSeconds(2));

            this.Dispatcher.Invoke(new Action(() =>
            {
                webBrowser1.Navigate(textBox1.Text);
                webBrowser2.Navigate(textBox1.Text);
                webBrowser3.Navigate(textBox1.Text);
            }), null);

        }).Start();
    }
}
Autogenesis answered 1/1, 2012 at 12:43 Comment(10)
i navigate inside a dispatcher call yes. Otherwise i'll get a runtime error. The only moment this happens is at start. once that tab has had a focus, it doesnt matter if you keep the focus or minimize the window. Also, the navigate_complete event doesn't get fired when navigating is completed. all of this only happens at startup of the app.Clair
What happens when you programatically focus all tabs at startup?Autogenesis
i was trying that a few times in different ways. how do you do that?Clair
tabItem2.Focus(); should do the trick. Call each next focus in the TabItem.GotFocus event.Autogenesis
i got quite a few tabs, i'll see if i can find a way to loop through them.Clair
TabControl.Items should give you all the tabs.Autogenesis
I found it, i've put it on 2 different places, in the constructor at the end of it. and in the window_loaded event. Either way its not navigating.Clair
it's a big ass project, i'll strip down everything in a new project and than i'll post the code or project.Clair
i added some code of the dispatcher for webbrowser control and textbox. couldn't get the mark up right, hope you can read it.Clair
let us continue this discussion in chatClair
C
0

It seems that this is the behavior of this control in WPF according to the docs.

Clair answered 27/3, 2012 at 20:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.