Welcome Guest Search | Active Topics | Sign In | Register

EO.WebBrowser preloading Options
Tamas Monus
Posted: Tuesday, June 14, 2016 2:59:22 AM
Rank: Advanced Member
Groups: Member

Joined: 5/6/2016
Posts: 30
Hi!

I'm aware that there is a threadrunner to load webpages without ui, but it would be awesome if the WebControl would support the feature of attaching a preloaded webview to it.

So basicly I think it would be great if we could do something like this:
- Preload a webview with a webpage through threadrunner
- When we actually have to show it, we create a WebControl and set its WebView to the preloaded WebView instance
eo_support
Posted: Tuesday, June 14, 2016 9:15:25 AM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,068
Hi,

In this case you do not need to use a ThreadRunner to do it. You would just do it in your main UI thread. If you use Windows Form, you can follow these steps:

1. Create a Form and create a WebControl in it;
2. Instead of calling the Form's Show method to display the form, you can access the Form's Handle property to ensure the Form's Handle is created. This will indirectly creates and initialize the WebView;

Once you are ready to display the WebView, set the WebControl's Parent to the new Parent control to move it. For example, you can set it a control in another form to move the WebControl from your invisible Form to the screen.

The key here is a WebView is always associated to a specific thread and that thread must pump messages. If message pumping stops, then the WebView won't do anything. This means two things:

1. This means it is not possible for you to move a WebView from a ThreadRunner to your main UI since the thread runner and the main UI are two different threads;
2. The above preloading method won't work if your main UI thread is busy. The internal works of the WebView only starts flowing when your application resumes pumping messages;

Hope this helps. Please feel free to let us know if you still have questions.

Thanks!
Tamas Monus
Posted: Tuesday, June 14, 2016 9:30:13 AM
Rank: Advanced Member
Groups: Member

Joined: 5/6/2016
Posts: 30
Hi!

Currently, I'm struggling with this issue. I'm using WPF, and sorry, but I can't wrap my head around what you said.

My first attempt to achive this was something like:
Quote:

var wnd = new Window();
var handle = new WindowInteropHelper(wnd).EnsureHandle();
_webView.Create(handle);


And later I attach this WebView to the WebControl, but it isn't show anything.

But according to what you wrote, then I should create my WebControl inside that window and preload the page there, then when I need to show my WebControl, then I just set the parent of the WebControl to an other element, like a Border?
eo_support
Posted: Tuesday, June 14, 2016 9:40:18 AM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,068
Hi,

The key is you need to use the WebControl wrapper class to create the WebView, not the WebView control directly. So it will be something like this:

Code: C#
//Create a WebControl in a Window
var wnd1 = new Window();
var webControl = new EO.WebBrowser.Wpf.WebControl();
wnd.Content = webControl;
var webView = webControl.WebView;
webView.Url = url;

//This will initializes the WebView
new WindowInteropHelper(wnd).EnsureHandle();


Then you can do this:

Code: C#
webControl.WebView = null;
anotherWebControlInAnotherWindow.WebView = webControl.webView;


Please let us know if this works for you.

Thanks!
Tamas Monus
Posted: Tuesday, June 14, 2016 10:25:20 AM
Rank: Advanced Member
Groups: Member

Joined: 5/6/2016
Posts: 30
I tell the whole to avoid misunderstandings.

There are some pages, that I have to preload and some that I don't. So I have a TemplatedControl called Browser. In its constructor I create a webControl and then I use the WebView it creates for itself to navigate and something like that.
Quote:

_webControl = new WebControl
{
HorizontalAlignment = HorizontalAlignment.Stretch,
VerticalAlignment = VerticalAlignment.Stretch,
Background = new SolidColorBrush(Colors.Transparent),
BorderThickness = new Thickness(0),
BorderBrush = new SolidColorBrush(Colors.Transparent)
};

ScrollViewer.SetHorizontalScrollBarVisibility(_webControl, ScrollBarVisibility.Disabled);

_webView = _webControl.WebView;
_webView.RegisterResourceHandler(new ZipHandler());
_webView.IsLoadingChanged += WebViewOnLoadingStateChanged;
_webView.KeyUp += WebViewOnKeyUp;


The I use _webView for almost like everything.
Now, for the pages that I have to preload, there is a service that manages this, and calls the Prefetch method on the Browser (The custom TemplatedControl where I use the WebControl).

This service first create a new instance of the Custom Browser control (which creates a WebControl in its constructor), then right after that it calls the Prefetch method of the Browser, which looks like this:
Quote:

_prefetchWindow = new Window();
_prefetchWindow.Content = _webControl;
new WindowInteropHelper(_prefetchWindow).EnsureHandle();


Now, I checked the IsCreated property of the WebView and it always returns false. I waited like 30secs to ensure that I won't call it too soon, but it always returns false.

Then, I thought that I give it a try either way, so I've done this in the OnApplyTemplate of my Custom Browser control
Quote:

if ((_webControl.Parent as Window) != null)
((Window) _webControl.Parent).Content = null;

_root.Children.Add(_webControl); // _root is a Grid here


It worked well, so the WebControl were putted inside the grid, but it wasn't preloaded, even tough I waited like 30 secs after Prefetch.

I hope that everything that I wrote make sense and understandable.
eo_support
Posted: Tuesday, June 14, 2016 10:31:55 AM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,068
How do you wait for 30 seconds?
Tamas Monus
Posted: Tuesday, June 14, 2016 10:42:39 AM
Rank: Advanced Member
Groups: Member

Joined: 5/6/2016
Posts: 30
First I load a page that I'm not preloading, (The service which preloads are started to preload) then I wait 30 secs, then I ask a page that should be preloaded. (Here the control just asks the service mentioned above to give it preloaded elements, and attach them to the Visualtree)

By the way, in the meantime, I tried like this:
Quote:

var wnd = new Window
{
Top = 9999,
ShowInTaskbar = false
};
wnd.Content = _webControl;
wnd.Show();
new WindowInteropHelper(wnd).EnsureHandle();

Notice the wnd.Show() call!
And like this it's preloading, but I would avoid the Show if possible, it feels unneccesary to show a window that won't be visible to the user in any way.

And my second problem is that when I attach this preloaded WebControl to the _root Grid, it reloads the page. But of course, I get back the same page again. Can I somehow avoid this reload?
eo_support
Posted: Tuesday, June 14, 2016 10:45:15 AM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,068
Tamas Monus wrote:
I wait 30 secs


Exactly how do you wait for 30 seconds? Do you call a function to wait for 30 seconds, or you just sit there to wait? What the program is doing during this period?
Tamas Monus
Posted: Tuesday, June 14, 2016 10:50:30 AM
Rank: Advanced Member
Groups: Member

Joined: 5/6/2016
Posts: 30
I just stay still. The program is idle in that time, it's displayed on the screen, but I don't interact with it in any way.
eo_support
Posted: Tuesday, June 14, 2016 10:52:22 AM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,068
Can you create a test app and send the test app to us? See here for more instructions:

http://www.essentialobjects.com/forum/test_project.aspx

This might be a problem on our side. The test app will help us understand exactly what you are doing and also help us to reproduce/verify the problem.

Thanks!
Tamas Monus
Posted: Tuesday, June 14, 2016 11:01:07 AM
Rank: Advanced Member
Groups: Member

Joined: 5/6/2016
Posts: 30
Ok, I'll create a sample as soon as I able to do it (I will have time around Friday or Monday, but I'll defintely create it, because we plan to use WebControl quite a lot). In the meantime, I should send a demo of my application to my boss tommorow, and it seems that If I call the Show, it works OK, and preloads the page (It would be better without it, but for the demo it would be acceptable).

So my question is, can I put this preloaded WebControl on the VisualTree with avoiding the reloading of the page?
In the OnApplyTemplate I call this code snippet to notice preloaded WebControl and to put to the correct VisualTree
Quote:

if ((_webControl.Parent as Window) != null)
((Window) _webControl.Parent).Content = null;

_root.Children.Add(_webControl); // _root is a Grid here

But the problem is, that for a second I saw the preloaded page, then it reloads the page (or at least it seems like that).

Edit:
Doesn't matter. It looks like its a problem on my end.
eo_support
Posted: Tuesday, June 14, 2016 10:19:52 PM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,068
OK. Thanks for the update. Please feel free to let us know if there is anything else.
Eurice
Posted: Wednesday, June 15, 2016 3:57:36 AM
Rank: Advanced Member
Groups: Member

Joined: 12/10/2014
Posts: 133
Hello Tamas,

I'm using the same trick to preload window/webview (top = 9999) , and you have to call show() on the window hosting you'r webview otherwise it wont load.

At this moment my app is preloading the entire window then display it; but it would be better to just preload the webview then move it in others windows.

Can you keep me updated if you suceed ?


Best regards
Eurice
Posted: Thursday, June 16, 2016 3:37:44 AM
Rank: Advanced Member
Groups: Member

Joined: 12/10/2014
Posts: 133
eo_support wrote:
Hi,

Code: C#
webControl.WebView = null;
anotherWebControlInAnotherWindow.WebView = webControl.webView;




This didn't worked for me, the webview disappeared from source window but did not appear on the target.
Tamas Monus
Posted: Thursday, June 16, 2016 3:57:54 AM
Rank: Advanced Member
Groups: Member

Joined: 5/6/2016
Posts: 30
I place the whole webControl to an other place instead of just the WebView. I didn't tried the other way, but that would be a cleaner way.

And I know it is a way to do this, but still it would be much better if there would be a WebView.Preload(string url) function supported by the EO. Which could preload a WebView in such a way that then we could just do something like:
Quote:

webControl.WebView = preloadedWebView;


I don't know how big of a work would be to do this (I didn't looked into it myself), but it would be really awesome. : )
Tamas Monus
Posted: Thursday, June 16, 2016 4:19:11 AM
Rank: Advanced Member
Groups: Member

Joined: 5/6/2016
Posts: 30
I've just noticed that even if I set the Windiw to Hidden, it will appear in the Alt + Tab list for a brief time if I call the Show() method on it. So this is definetly a no go in the long run. I will create that sample for you as soon as I able. Preferably today afternoon or tomorrow.
Eurice
Posted: Thursday, June 16, 2016 5:55:50 AM
Rank: Advanced Member
Groups: Member

Joined: 12/10/2014
Posts: 133
Tamas Monus wrote:

it would be much better if there would be a WebView.Preload(string url) function supported by EO


Huge +1 !
Tamas Monus
Posted: Friday, June 24, 2016 2:49:53 AM
Rank: Advanced Member
Groups: Member

Joined: 5/6/2016
Posts: 30
I've just sent you a Sample project about this problem. I am sorry, that It took me so long, I had other tasks that I have to do first.

Please inform me if there will be any kind of progress about this issue, it's really important in our application.
eo_support
Posted: Friday, June 24, 2016 10:20:26 AM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,068
Hi,

We have received the sample application. We will look into it and get back to you as soon as possible.

Thanks!
eo_support
Posted: Wednesday, June 29, 2016 1:41:48 PM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,068
Hi,

We have looked into this issue and it appears that you can not preload a WebView this way. The root of the problem is WPF does not invoke it's internal Measure/Layout/Template logic until the window is visible. We are adding a static WebView.Preload method that can do the preload internally and it should be available in our next build.

Thanks!


You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.