I was creating a browser window for my WPF application. During the visibility change I am loading the URL, but when I change the URL content and load the same URL it is showing previous content first, then after a blinking it shows the updated data.
void OnWindowVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
{
if (!IsBrowserInitialized) return;
if (window.Visibility == Visibility.Visible)
{
Dispatcher.BeginInvoke(new Action(() =>
{
LoadNewUrl();
window.Activate();
}));
}
else
{
Dispatcher.BeginInvoke(new Action(() =>
{
ChromeBrowser.LoadHtml("<html><body><h1></h1></body></html>");
}));
}
}
Suppose the URL contains "ABCD" as data. First time it is showing the correct content. After the update the data becomes "ABCDEF". Now on Load() the initial content is showing then the updated content.
Is there anything else I need to do for avoiding this issue?
I'm not sure what LoadHtml() does, it's not a part of the native CEF API. In any case the blank page is about:blank, i.e. ChromeBrowser.Load("about:blank").
Are you aware of stopping all activities in the hidden browser? It seems to be the issue - you load an empty page and hide the window, the browser stops any activities, then you activate the window and still see an old content, then an empty page causes "blinking", and finally a new content is shown.
You should catch change visibility request, cancel it, load about:blank and hide the window on load completion. The client handler has appropriate events.
Related
I have an Embedded Web browser control in WPF application developed with prism. In Home page on left pane there is a grid implemented which has list of URL's, when double clicked new embedded browser view is resolved and added to the region. I pass URL to object such it loads the web page in web browser control. The issue I am facing here is for the first time when any url is double clicked on the life side grid, the application is freezing till the page is loaded in web browser control I have performed my implementation in xaml.cs by using dispatcher. Please find the code below..
public BrowserView()
{
InitializeComponent();
}
void WebBrowserControlView_Loaded(object sender, RoutedEventArgs e)
{
UrlStore = ViewModel.Model.Url;
string Url = UrlStore;
Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() => { UrlLoad(Url); }));
}
private void UrlLoad(string Url)
{
//All implementations were run on background thread.
}
I am not sure why there is a lag initially. However, for later operations there is no lag.
I have two wpf windows in my wpf application.
1) When i click on the load button it loads the second Window. The secong window takes 15 to 20 secs to load.
How do i add a progress bar to show a loading window and when the second window loads close the progress bar.
I was recently working on a loading window for my app where you click the app and it takes about 10s to load. I have a loading window with an intermediate loading bar. The key was to put the loading window in a different thread to enable the animation to run while it was loading the other window on the main thread. The problem was to make sure we do stuff propertly (like when we close we close the window should stop the thread... etc).
In the code below... LoadingWindow is a small window with a progress bar on it, SecondWindow would be the window that is slow to load.
public void OnLoad()
{
Dispatcher threadDispacher = null;
Thread thread = new Thread((ThreadStart)delegate
{
threadDispacher = Dispatcher.CurrentDispatcher;
SynchronizationContext.SetSynchronizationContext(new DispatcherSynchronizationContext(threadDispacher));
loadingWindow = new LoadingWindow();
loadingWindow.Closed += (s, ev) => threadDispacher.BeginInvokeShutdown(DispatcherPriority.Background);
loadingWindow.Show();
System.Windows.Threading.Dispatcher.Run();
});
thread.SetApartmentState(ApartmentState.STA);
thread.IsBackground = true;
thread.Start();
// Load your second window here on the normal thread
SecondWindow secondWindow = new SecondWindow();
// Presumably a slow loading task
secondWindow.Show();
if (threadDispacher != null)
{
threadDispacher.BeginInvoke(new Action(delegate
{
loadingWindow.Close();
}));
}
}
There are many ways you can accomplish that. An easy way would be to create a third window or panel with the progress bar or a waiting animation. That third window is in charge of loading your second window and get displayed as soon as you click the load button on the first window. When loading of the second window is completed, the third window with the progress bar closes and the second window gets displayed.
hope this helps.
You could use the BusyIndicator as part of the WPF extended toolkit. You can download it here: http://wpftoolkit.codeplex.com/wikipage?title=BusyIndicator
On immediate loading of the new window before you do your expensive processing that takes forever, you can set the IsBusy to true. When processing is done, set IsBusy back to false. This method involves wrapping your XAML in the BusyIndicator in the 2nd window, which may or may not be what you want.
In method that is working in the background, i have two important lines :
createPopup();
MessageBox.Show(sth);
more lines
more lines
createPopup() just creates a popup, adds a grid as a child and shows popup.
My question is, why first shows up messageBox, then shows up Popup, which appears after all lines in this method done ? How could I make this popup to show before all lines in this method will be done ?
All the UI changes are normally queued up and will be shown at once on the screen.
And this does not include MessageBox. So it shows up immediately and prevents the execution, until user clicks on Ok. Hence eventhough your popUP is first executed, it will be shown in the UI only after the MessageBox.
For your problem, Try placing your MessageBox.Show(something) in a separate thread.
createPopup();
Dispatcher.BeginInvoke(() =>
{
MessageBox.Show("some message");
});
more lines
more lines
Give it a try. I am not sure whether it solves your problem or not as I dnt know the code in createPopUp() method.
Creating the pop-up, does not actually draw it on the screen until the Layout event. If you want to ensure that the pop-up has been drawn before you display the pop-up, attach an event handler to the pop-up's LayoutUpdated event and display the message box from within that event handler. Be sure to detach the event handler as well or you will see multiple message boxes.
public InitPage()
{
Popup popup = new Popup();
popup.LayoutUpdated += popup_LayoutUpdated;
LayoutRoot.Controls.Add(popup);
}
void popup_LayoutUpdated(object sender, object e)
{
popup_LayoutUpdated -= popup_LayoutUpdated;
MessageBox.Show("hello");
}
I have a Win form application (VS 2010 / C#) and I'm trying to figure out how to refresh pages without a refresh button. Currently I can refresh a page (basically to reset the data bindings) with a refresh button containing code something like this (this.refresh() does not seem to work for some reason):
this.Hide();
AccountSettings AS = new AccountSettings();
AS.ShowDialog();
An example I have is a page with numerous settings including data grids with CellClick events. When I click a cell I can make changes to a database. I hit close to go back to the Settings page but the only way for me to see the changes are to refresh() the page via the button.
So the short of it is, is there any way to refresh a form page from another form page?
For instance, when I click the Save button or close the child window.
Maybe pass the original form as an argument to the second form:
Form2 frm2 = new Form2(this);
And in Form2:
Form1 frm1;
public Form2(Form1 frm1)
{
InitializeComponent();
this.frm1 = frm1;
}
And then have in Form2:
frm1.Update();
Refresh on winform controls repaints the control itself. I find it useful to create a method that just loads my controls with the proper data, and then call it as necessary. (Including Form load)
private void ResetData()
{
//code to update settings
}
If you are showing the form that is closing as a dialog also you can take advantage of that, and check the status of the dialog instead of just opening it.
Form2 dlg = new Form2();
if (dlg.ShowDialog == System.Windows.Forms.DialogResult.OK) {
//code that updates your data
ResetData();
}
If its not a dialog there are a few things you could do and how your application works would make one method better than others. Here is just one example.
If your changes are something you don't need access to data from the other window to update you can handle the closed event of the form you create.
Create a class level variable to hold the form that is opened, so that you can also remove the event handlers you create:
private Form2 frm;
To create an instance of the form, and add the close event handler:
frm = new Form2();
frm.FormClosed += OnForm2Closed;
The event handler method:
private void OnForm2Closed(object sender, FormClosedEventArgs e)
{
ResetData();
frm.FormClosed -= OnForm2Closed;
}
I have a WPF System.Windows.Controls.WebBrowser control in a Window. A user can enter information and hit a submit button into the webpage displayed by the WebBrowser. After the page posts back it uses a scripting object to communicate with my application. I need to make sure that once the submit button has been pressed, the form doesn't close or otherwise stop waiting for the web page to post back. It would be great if I could check the state of the WebBrowser or its document via a property like "IsLoading" and cancel any actions if it is loading. I didn't see anything like that so I was thinking of setting a flag on the Navigating event and unsetting it on the Navigated or LoadCompleted event, but there is a case where I click a link on the web page (tied to javascript, it doesn't go to a new page) where Navigating is fired, but Navigated and LoadCompleted never fire. Is there a way to determine the state of the browser on demand?
As per MSDN if the Navigating event gets invoked then the Navigated Event will also get fired unless you explicitly Cancel the navigation. I tried the below code-snippet it seems to be working fine. (i.e) whenever the Navigated event is getting fired following Navigating event.
void Window1_Loaded(object sender, RoutedEventArgs e)
{
browser = new WebBrowser();
browser.Navigate(new Uri("http://www.google.com"));
browser.Navigating += new NavigatingCancelEventHandler(browser_Navigating);
browser.Navigated += new NavigatedEventHandler(browser_Navigated);
}
void browser_Navigating(object sender, NavigatingCancelEventArgs e)
{
Console.WriteLine("Loading Webpage !!");
}
void browser_Navigated(object sender, NavigationEventArgs e)
{
Console.WriteLine("Webpage Loaded !!");
}
If this is not what you are looking for, then provide the webpage URL in which you are facing the issue.
No, there does not appear to be a way to query the WPF browser's status on demand. I settled on my original idea of setting my own flag in the Navigating event handler and unsetting it in the Navigated event handler. It was not working reliably for me because there was a script that canceled navigation (javascript:void(0)).