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.

Yustme
  • 6,125
  • 22
  • 75
  • 104
  • How would it navigate if it is minimized? – rene Jan 01 '12 at 12:18
  • Why isn't this an issue in winforms? – Yustme Jan 01 '12 at 12:31
  • 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. – Tomislav Markovski Jan 01 '12 at 12:31
  • 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? – Yustme Jan 01 '12 at 12:40
  • See my answer below, invoking the Dispatcher might solve your problem. – Tomislav Markovski Jan 01 '12 at 12:44
  • 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. – Tomislav Markovski Jan 01 '12 at 14:40
  • see my last post under your answer. – Yustme Jan 01 '12 at 14:52
  • 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. – paparazzo Jan 01 '12 at 16:58
  • '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. – Yustme Jan 01 '12 at 18:25
  • no one that can explain this behavior or fix it? – Yustme Jan 03 '12 at 17:20
  • 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. – Léon Pelletier Jun 03 '13 at 00:01

2 Answers2

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();
    }
}
Gayot Fow
  • 8,710
  • 1
  • 35
  • 48
Tomislav Markovski
  • 12,331
  • 7
  • 50
  • 72
  • 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. – Yustme Jan 01 '12 at 12:59
  • What happens when you programatically focus all tabs at startup? – Tomislav Markovski Jan 01 '12 at 13:02
  • i was trying that a few times in different ways. how do you do that? – Yustme Jan 01 '12 at 13:14
  • `tabItem2.Focus();` should do the trick. Call each next focus in the `TabItem.GotFocus` event. – Tomislav Markovski Jan 01 '12 at 13:20
  • i got quite a few tabs, i'll see if i can find a way to loop through them. – Yustme Jan 01 '12 at 13:50
  • `TabControl.Items` should give you all the tabs. – Tomislav Markovski Jan 01 '12 at 13:53
  • 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. – Yustme Jan 01 '12 at 13:55
  • it's a big ass project, i'll strip down everything in a new project and than i'll post the code or project. – Yustme Jan 01 '12 at 14:22
  • i added some code of the dispatcher for webbrowser control and textbox. couldn't get the mark up right, hope you can read it. – Yustme Jan 01 '12 at 14:30
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/6290/discussion-between-yustme-and-tomislav-markovski) – Yustme Jan 01 '12 at 14:43
0

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

Yustme
  • 6,125
  • 22
  • 75
  • 104