I'm developing a Windows Phone application.
I'm using WebBrowser control and I want to show to users when is loading a page. I've used events:
private void Browser_Navigating(object sender, Microsoft.Phone.Controls.NavigatingEventArgs e)
{
LoadingText.Visibility = System.Windows.Visibility.Visible;
}
private void Browser_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
{
LoadingText.Visibility = System.Windows.Visibility.Collapsed;
}
But it doesn't work.
Any advice?
I think your problem is in the navigated event - this
From msdn
Occurs when the WebBrowser control has navigated to a new document and has begun loading it.
This obviously could be long before the document is actually rendered.
I'm not sure there's any event to use to determine when the page is fully loaded and is rendered.
In iron7, I detect when the editor is loaded by using a timer - that timer keeps trying to call javascript methods in the script - I know these are only available after the document javascript ready occurs.
Try using the LoadCompleted event:
private void Browser_LoadCompleted(object sender, NavigationEventArgs e)
{
LoadingText.Visibility = System.Windows.Visibility.Collapsed;
}
This ensures that once everything is rendered the loading bar will disappear.
See the msdn page: http://msdn.microsoft.com/en-us/library/microsoft.phone.controls.webbrowser.loadcompleted(v=VS.92).aspx
(I think Stuart was looking at the Windows Forms implementation of WebBrowser rather than the Phone Control)
Related
I'm using shell to navigate in my Xamarin Forms app. I want my settings to be in a Modal dialog which is navigated to by calling PushModalAsync. In that settings page I want to navigate to other pages, eg password change. But since I'm not using NavigationPage I cannot get it to work.
How do one use Shell with Modal and navigate within that Modal page?
I can get it to work by setting my SettingsPage as a new MainPage. But then I don't get the modal navigation animation.
using NavigationPage will probably solve the problem but then I will
no longer use Shell which I want to use.
I think wrap your Settings page in a NavigationPage would solve your problem. You can still use Shell after using NavigationPage.
For example, you can do some push actions in the SettingPage:
private async void Button_Clicked(object sender, EventArgs e)
{
await Navigation.PushAsync(new BearDetailPage());
}
In the BearDetailPage, if you want to use Shell, you can dismiss the SettingPage by send a message usingMessagingCenter:
private async void Button_Clicked(object sender, EventArgs e)
{
await Navigation.PopToRootAsync(false);
MessagingCenter.Send<BearDetailPage>(this, "BackToShell");
}
And in the SettingPage, subscribe that message:
public SettingPage()
{
InitializeComponent();
MessagingCenter.Subscribe<BearDetailPage>(this, "BackToShell", (sender) =>
{
// Do something whenever the "BackToShell" message is received
this.Navigation.PopModalAsync();
});
}
If you don't want the navigationbar in the SettingPage, you can just hide it.
My mainpage call to Page1. I add a webbrowser control to the Page1. When the webbrowser load data complate, I go the background.Then, i back my Page1, webbrowser reload data. How to stop reload it?
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
_mlink = NavigationContext.QueryString["link"];
web.Navigate(new Uri(_mlink, UriKind.Absolute));
}
You can use the NavigationEventArgs.NavigationMode property to determine which direction the navigation is coming from.
The available options can be found here (MSDN), but listed out, they are:
New
Back
Forward
Refresh
So my tip would be to determine which value of this you want to navigate the web browser control on (I would guess New).
NavigationEventArgs.NavigationMode works only in windows phone 8. So edit the code like this.
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
_mlink = NavigationContext.QueryString["link"];
if(web.Source.AbsolutePath!=_mlink)
web.Navigate(new Uri(_mlink, UriKind.Absolute));
}
i'm pretty new in the .net programming and i would like to get some suggestions.
I'm trying to create an easy client GUI application using the VS2010 Designer to create a single form in which i have:
1 comboBox, (containing the list of possible commands)
1 button, (used to execute the command selected in the combobox)
1 picturebox (in which i display images received from my server application)
I was able to create my client application and display a different image in the picturebox received from the server everytime i press the button.
What i would like to do is a not blocking loop in the event button click so that as long as the the client combobox command is set to start imaging, the images sent by the server are displayed in the picturebox and it stops when the client combobox command is set to stop imaging.
I'm not sure about how to do that because if i try and loop in the event button click, the GUI becomes unresponsive and i don't have a chance to change the command in the combobox.
Any help would be much appreciated.
Thanks.
Here's a "cheap" way to update the GUI by using the ReportProgress feature of the BackgroundWorker class. First drop a BackgroundWorker object on your form. Then...
private void Form1_Load(object sender, EventArgs e)
{
backgroundWorker1.DoWork += DoWork;
backgroundWorker1.ProgressChanged += UpdateGui;
backgroundWorker1.WorkerReportsProgress = true;
backgroundWorker1.RunWorkerAsync();
}
private void DoWork(object sender, DoWorkEventArgs e)
{
while (true)
{
System.Threading.Thread.Sleep(1000);
backgroundWorker1.ReportProgress(0);
}
}
void UpdateGui(object sender, ProgressChangedEventArgs e)
{
textBox1.Text = DateTime.Now.ToLongTimeString();
}
Is it possible to detect the DOM elements under a spot the user taps on a website using the WP7 WebBrowser control? I would like to let the user identify certain sections of the rendered page.
Yes. This code works pretty well for me:
private void button1_Click(object sender, RoutedEventArgs e)
{
// first define a new function which serves as click handler
webBrowser1.InvokeScript("eval", "this.newfunc_eventHandler = function(e) { window.external.notify(e.srcElement.tagName); }");
// attach function to body
webBrowser1.InvokeScript("eval", "document.body.addEventListener('click', newfunc_eventHandler, false);");
}
private void webBrowser1_ScriptNotify(object sender, NotifyEventArgs e)
{
// this should be called every time you tap an element; the value should be its tag name
Debug.WriteLine(e.Value);
}
It goes along Justin's answer (who beat me while coding). It first defines a click handler which then is attached to the page's body (all via InvokeScript). Every time you tap an element ScriptNotify should be called on the WebBrowser reporting the tapped element's tag name.
Make sure you have set IsScriptEnabled true for your browser control.
I'm guessing you'd have to build something off of the ScriptNotify Event.
At that point, you would register a JavaScript Event handler as usual but that event handler would, in turn, call window.external.notify("someMessageToHandle");. You would then have to route the calls appropriately.
If you don't have the ability to add the JavaScript event handlers directly on the page, you could instead add them using WebBrowserControl.InvokeScript.
I taken two Images & added event (MouseButtonDown) for them.
When first image handles event to open Gallery. Second image handles events for open camera.
When user has choosed his image from the gallery, I want to navigate to next page. Its navigates. But before completing navigation process, it displays MainPage & then moves toward next page. I didnt want to display the MainPage once user chooses the image from the gallery.
Plz help.
Thanks in advance.
public partial class MainPage : PhoneApplicationPage
{
PhotoChooserTask objPhotoChooser;
CameraCaptureTask cameraCaptureTask;
// Constructor
public MainPage()
{
InitializeComponent();
objPhotoChooser = new PhotoChooserTask();
objPhotoChooser.Completed += new EventHandler<PhotoResult>(objPhotoChooser_Completed);
cameraCaptureTask = new CameraCaptureTask();
cameraCaptureTask.Completed += new EventHandler<PhotoResult>(objCameraCapture_Completed);
}
void objPhotoChooser_Completed(object sender, PhotoResult e)
{
if (e != null && e.TaskResult == TaskResult.OK)
{
//Take JPEG stream and decode into a WriteableBitmap object
App.CapturedImage = PictureDecoder.DecodeJpeg(e.ChosenPhoto);
//Delay navigation until the first navigated event
NavigationService.Navigated += new NavigatedEventHandler(navigateCompleted);
}
}
void navigateCompleted(object sender, EventArgs e)
{
//Do the delayed navigation from the main page
this.NavigationService.Navigate(new Uri("/ImageViewer.xaml", UriKind.RelativeOrAbsolute));
NavigationService.Navigated -= new NavigatedEventHandler(navigateCompleted);
}
void objCameraCapture_Completed(object sender, PhotoResult e)
{
if (e.TaskResult == TaskResult.OK)
{
//Take JPEG stream and decode into a WriteableBitmap object
App.CapturedImage = PictureDecoder.DecodeJpeg(e.ChosenPhoto);
//Delay navigation until the first navigated event
NavigationService.Navigated += new NavigatedEventHandler(navigateCompleted);
}
}
protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
{
e.Cancel = true;
}
private void image1_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
objPhotoChooser.Show();
}
private void image2_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
cameraCaptureTask.Show();
}
To my knowledge when you use one of the choosers, like the Photo gallery or the camera, when your application is activating it will take it back to the page you left it. I don't think there is a way to get around this itself. What you would have to do is catch the Activating event in your main page code and Navigate to the desired page from there.
Now I am not completely sure how you would pass the image from the MainPage to the target page. It does not look like there is a property in the Navigation service to store this value. But you could either set it in an application wide variable, ModelView or even store it in the Isolated Storage area.
You could work around this by navigating to an intermediate blank page and have that intermediate page launch the tasks. When the tasks are completed you can then navigate as normal to your new page and only this blank page will show in transit.
Chris is correct that some of the tasks will navigate away from your app (effectively tombstoning it) and will the re-activate your application when the user returns from the task. For the camera this is particularly difficult, as to my knowledge there is no simple way to detect when you are returning from the camera. Also the camera doesn't work when attached to the debugger or Zune software (at least this is true on my HTC Surround), which makes troubleshooting quite difficult!
In my WP7 Barcode Scanning application I ended up using flags on the PhoneApplicationService class to help track where the navigation events are coming from. Something like:
PhoneApplicationService.Current.State["ReturnFromSampleChooser"] = true;
You can then check for these flags in the PhoneApplicationPage_Loaded or OnNavigatedTo method of your main page and redirect to the desired page as needed. Just make sure to clear the flag and be careful to not cause any loops in the navigation, as that might make your app fail certification (back button must ALWAYS work correctly).
For an example of how to use the camera and set/clear flags using PhoneApplicationService check out the source code for the Silverlight ZXing Barcode Library. You can download the full source here or browse the files online.