Loading ajax web page content with a webbrowser control - ajax

I'm using WebBrowser control for parsing a website.The results are good but I have problems for those kind of websites that require ScrollDown to load entire pages Via Ajax.I Tried to fire the "DocumentCompleted" event but seems that for this step the document is already loaded in control and just the top part (I mean without scrolling).
I also tried to send keys and force scroll down or execute javascript for various WebBrowser states but without success.
I need help,
Thanks,

I found the answer for this question.What I had to know is in the following code:
public partial class Form1 : Form
{
bool finished=false;
public Form1()
{
InitializeComponent();
this.WindowState=FormWindowState.Maximized;
webBrowser1.ScriptErrorsSuppressed=true;
this.Show();
Wait4Load();
string aaa = webBrowser1.DocumentText;
}
void webBrowser1_DocumentCompleted(objectsender,WebBrowserDocumentCompletedEventArgs e)
{
if (webBrowser1.ReadyState == WebBrowserReadyState.Complete)
{
finished = true;
button1.PerformClick();
}
}
void Wait4Load()
{
webBrowser1.DocumentCompleted+=new WebBrowserDocumentCompletedEventHandler(webBrowser1_DocumentCompleted);
button1.Click+=new EventHandler(button1_Click);
if(!finished)
{
Application.DoEvents();
Thread.Sleep(2000);
}
finished = false;
}
void button1_Click(object sender, EventArgs e)
{
//footerWrapper
while(webBrowser1.ReadyState != WebBrowserReadyState.Complete)
Application.DoEvents();
while(webBrowser1.IsBusy)
Application.DoEvents();
webBrowser1.Navigate("javascript:setTimeout(location.hash='#footerWrapper',2000)");
//Thread.Sleep(3000);
finished=true;
}
}`

Related

How do I listen to UWP Xaml Slider manipulation start/end events?

What events should I listen to on a UWP Xaml Slider to determine when the user begins and ends manipulation.
This functionality is important when you have a slider that represents some continuously changing app state (say, an animation time) and you want to pause the update when the user interacts with the slider.
This question has been answered for WPF and Windows Phone, but not UWP. The other solutions do not work, or are incomplete, for UWP.
You need to listen to interaction events from a couple of the elements of the Slider template: the Thumb, and the Container. This is because the user can manipulate the thumb directly by clicking and dragging it, but also they can click anywhere on the slider and the thumb will jump to that location (even though it looks like you are then manipulating the Thumb, actually the thumb is just being relocated every time the mouse moves - you are still interacting with the container).
There are a couple caveats:
the thumb and container both process their input events and do not pass them on, so you need to use the AddHandler method of attaching RoutedEvent handlers so that you get events which have already been processed.
you need to attach the event handlers after the control template has been applied, which means you need to subclass the Slider to override a protected method.
The RoutedEvent handler information is covered here: https://learn.microsoft.com/en-us/windows/uwp/xaml-platform/events-and-routed-events-overview#registering-handlers-for-already-handled-routed-events
The following SliderEx class adds some events which can be used to detect when the user begins/ends interacting with the slider:
public class SliderEx : Slider
{
public event EventHandler SliderManipulationStarted;
public event EventHandler SliderManipulationCompleted;
public event EventHandler SliderManipulationMoved;
private bool IsSliderBeingManpulated
{
get
{
return this.isContainerHeld || this.isThumbHeld;
}
}
private bool isThumbHeld = false;
private bool isContainerHeld = false;
protected override void OnApplyTemplate()
{
base.OnApplyTemplate();
var thumb = base.GetTemplateChild("HorizontalThumb") as Thumb;
if (thumb == null)
{
thumb = base.GetTemplateChild("VerticalThumb") as Thumb;
}
if (thumb != null)
{
thumb.DragStarted += this.Thumb_DragStarted;
thumb.DragCompleted += this.Thumb_DragCompleted;
thumb.DragDelta += this.Thumb_DragDelta;
}
var sliderContainer = base.GetTemplateChild("SliderContainer") as Grid;
if (sliderContainer != null)
{
sliderContainer.AddHandler(PointerPressedEvent,
new PointerEventHandler(this.SliderContainer_PointerPressed), true);
sliderContainer.AddHandler(PointerReleasedEvent,
new PointerEventHandler(this.SliderContainer_PointerReleased), true);
sliderContainer.AddHandler(PointerMovedEvent,
new PointerEventHandler(this.SliderContainer_PointerMoved), true);
}
}
private void SliderContainer_PointerMoved(object sender,
Windows.UI.Xaml.Input.PointerRoutedEventArgs e)
{
this.InvokeMove();
}
private void SliderContainer_PointerReleased(object sender,
Windows.UI.Xaml.Input.PointerRoutedEventArgs e)
{
this.SetContainerHeld(false);
}
private void SliderContainer_PointerPressed(object sender,
Windows.UI.Xaml.Input.PointerRoutedEventArgs e)
{
this.SetContainerHeld(true);
}
private void Thumb_DragDelta(object sender, DragDeltaEventArgs e)
{
this.InvokeMove();
}
private void Thumb_DragCompleted(object sender, DragCompletedEventArgs e)
{
this.SetThumbHeld(false);
}
private void Thumb_DragStarted(object sender, DragStartedEventArgs e)
{
this.SetThumbHeld(true);
}
private void SetThumbHeld(bool held)
{
bool wasManipulated = this.IsSliderBeingManpulated;
this.isThumbHeld = held;
this.InvokeStateChange(wasManipulated);
}
private void SetContainerHeld(bool held)
{
bool wasManipulated = this.IsSliderBeingManpulated;
this.isContainerHeld = held;
this.InvokeStateChange(wasManipulated);
}
private void InvokeMove()
{
this.SliderManipulationMoved?.Invoke(this, EventArgs.Empty);
}
private void InvokeStateChange(bool wasBeingManipulated)
{
if (wasBeingManipulated != this.IsSliderBeingManpulated)
{
if (this.IsSliderBeingManpulated)
{
this.SliderManipulationStarted?.Invoke(this, EventArgs.Empty);
}
else
{
this.SliderManipulationCompleted?.Invoke(this, EventArgs.Empty);
}
}
}
}

Why entry's Focus() method isn't working from page's constructor?

In Xamarin Forms, when I use the following code:
public SomePage()
{
InitializeComponent();
someEntry.Focus();
}
the code entry isn't focused by default, however, if I use the following code:
protected override void OnAppearing()
{
base.OnAppearing();
someEntry.Focus();
}
it works as needed (entry is focused). Why is that? Isn't codeEntry already existing and sitting at it's place, fully functional, after InitializeComponent() call? I mean, I sure can change Text property from page constructor.
In Xamarin, every control has equivalent view renderer, that is native UI element which will only be created when control is added to the native element hierarchy. In constructor, native element for entry is not yet created. However, in OnAppering, entry's corresponding native element is created so it can get the focus.
Also this seems like a bug as Xamarin is storing state and applying it when creating the native UI element. Its time to file a bug !!!
When I use Shell this don't work anymore.
protected override void OnAppearing()
{
base.OnAppearing();
someEntry.Focus();
}
But this does work:
protected async override void OnAppearing()
{
base.OnAppearing();
await Task.Delay(100);
someEntry.Focus();
}
File.xaml
<Entry x:Name="txtLPN" Placeholder="Scan LPN." Grid.Row="1" Grid.Column="0" FontSize="15" Focused="txtLPN_Focused" />
File.cs >>>>>
private void txtLPN_Focused(object sender, FocusEventArgs e)
{
txtLPN.CursorPosition = 0;
if (!string.IsNullOrEmpty(txtLPN.Text))
txtLPN.SelectionLength = txtLPN.Text.Length;
}
protected async override void OnAppearing()
{
base.OnAppearing();
await Task.Delay(600);
txtLPN.Focus();
}
I tried all of the above. I think because my page is a pop-up and has some animation none of the above worked. However this worked for me:
BackgroundWorker setFocus = new BackgroundWorker();
In constructor
setFocus.DoWork += SetFocus_DoWork;
private void SetFocus_DoWork(object sender, DoWorkEventArgs e)
{
bool worked = false;
while (!worked)//will keep trying until it can set focus (when MyEntry is rendered)
{
Thread.Sleep(1);
MainThread.InvokeOnMainThreadAsync(()=> worked = MyEntry.Focus());
}
}
protected override void OnAppearing()
{
base.OnAppearing();
if(!setFocus.IsBusy)
{
setFocus.RunWorkerAsync();
}
}
You may want to add something to handle if "worked" is never set to true like try this for a few seconds.
You can use the Xamarin Community Toolkit LifecycleEffect to call some code when the renderer for the Entry is initialized/cleaned up. Combine this with OnAppearing to reliably show the keyboard without using cheap DoEvents hacks like await Task.Yield() or await Task.Delay(100).
XAML:
<Entry x:Name="userName">
<Entry.Effects>
<xct:LifecycleEffect Loaded="LifecycleEffect_Loaded" Unloaded="LifecycleEffect_Unloaded" />
</Entry.Effects>
</Entry>
C#:
private bool userNameLoaded = false;
protected override void OnAppearing()
{
base.OnAppearing();
if (userNameLoaded)
{
userName.Focus();
}
}
private void LifecycleEffect_Loaded(object sender, System.EventArgs e)
{
if (sender == userName)
{
userNameLoaded = true;
userName.Focus();
}
}
private void LifecycleEffect_Unloaded(object sender, System.EventArgs e)
{
if (sender == userName)
{
userNameLoaded = false;
}
}
OnAppearing won't be called after background + resume on iOS, so you'll need to hook into Application.OnResume to show focus if the user backgrounds + restores the app on iOS:
protected override void OnResume()
{
if (Xamarin.Forms.Device.RuntimePlatform == Xamarin.Forms.Device.iOS)
{
// TODO: Use Messenger, check Shell.Current.CurrentPage, etc. to set focus.
}
}
underneath of Xamarin form it is android activity or iOS 's UIviewController's page life cycle works. someEntry.Focus(); will not work in your constructor

Simple navigation in Windows 8 web view

I'm working on porting a Windows Phone 8 application to tablet, and I've bumped into a problem with the WebView API. In Windows Phone 8 and Windows 8.1, the WebBrowser and WebView controls both have a GoBack() method. However, I need my application to be compatible for Windows 8, whose WebView API does not have such a method. Are there any alternatives/workarounds that anyone's used for Windows 8 apps?
In the end I just ended up writing a wrapper for the WebView to manage the navigation stack. Here's the relevant code, for anyone who's interested. Note that I only needed to handle backwards navigation, so I used a Stack. If forwards navigation is also required, it'd probably make sense to replace the Stack with a List and store the index of the current page instead.
public class WebViewWrapper
{
private Stack<Uri> _navigationStack;
private Uri _currentUri;
public WebView WebView { get; private set; }
public bool CanGoBack
{
get { return _navigationStack.Count > 0; }
}
public WebViewWrapper(WebView _webView)
{
_navigationStack = new Stack<Uri>();
WebView = _webView;
WebView.LoadCompleted += (object s, NavigationEventArgs e) => {
if (_currentUri != null)
{
_navigationStack.Push(_currentUri);
}
_currentUri = e.Uri;
};
}
public void GoBack()
{
if (CanGoBack)
{
_currentUri = null;
WebView.Navigate(_navigationStack.Pop());
}
}
}
An example of usage would be as follows:
// Code behind for a view called WebBrowserPage
public sealed partial class WebBrowserPage : Page
{
private WebViewWrapper _webViewWrapper;
public WebBrowserPage()
{
// webView is a WebView in the xaml with x:Name="webView"
_webViewWrapper = new WebViewWrapper(webView);
}
// Other code for navigating to a Uri specified in a ViewModel.
// Event handler for a back button press
private void BackButton_Click(object sender, RoutedEventArgs e)
{
if (_webViewWrapper.CanGoBack)
{
_webViewWrapper.GoBack();
}
else
{
// Code that executes a command in the ViewModel to leave the WebBrowserPage
}
}
}
WinRT XAML Toolkit has a WebBrowser control that does some of that, but I haven't used it in any app, so I can't vouch for its quality.

Can i stop back button of hardware in wp7?

My scenario is , When I navigate to a new page It takes some time to load the content. And for that duration of time, If I press back key it throws exception for some reason. So I want to stop the back key behaviour for that much duration and when content is fully loaded, user can press the back key and then navigate to previous page. I just want to be clear, Is it permitted in application certification requirement from microsoft so that my app could not get rejected. so please give answer.
You could do something like this:
bool flag = false;
// Assuming this is where you can handle executions during loading
loading()
{
flag = true;
}
// After loading is completed
loadComplete()
{
flag = false;
}
// Handle back button
protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
{
if (flag)
{
e.Cancel = true;
}
}
As long as you don't lock the user to never allow him to go back, it should pass the certification.
In xaml
<phone:PhoneApplicationPage
.....
BackKeyPress="PhoneApplicationPage_BackKeyPress">
In code
private void PhoneApplicationPage_BackKeyPress(object sender, System.ComponentModel.CancelEventArgs e)
{
e.Cancel = CouldStepBack();
}
private bool CouldStepBack()
{
// todo return true, when load comleted
// else return false
}
And if you need you also can clean stack of pages (optional)
protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (NavigationService.CanGoBack)
{
while (NavigationService.RemoveBackEntry() != null)
{
NavigationService.RemoveBackEntry();
}
}
base.OnNavigatedTo(e);
}
Hope its help

Silverlight TabItem template not working correctly

In a SL4 application i need to restyle my TabItems (actually add a button in the header).
So i took the TabItem's control template from here and added the functionality i wanted.
This seems to work fine, (i could dynamically add tabitems) with one exception:
i think this posted control template is behaving somehow "arbitrary": every time the mouse hoovers over a non selected TabItem header, this gets selected WHITHOUT clicking!! (afaik this is not the default behavior: the user user has to click a header to make this tabitem the selected one).
I tried to find why it is behaving like this, with no luck!
Is there someone who can enlighten my darkness???
Thanks in advance!
Well it turns out the error was not in the control template but in the class, the style was applied to.
In detail: the class the style was applied to is the following (in it you will see my comment about the "wrong behavior"):
public class WorkspaceViewModel : TabItem
{
public WorkspaceViewModel()
{
DefaultStyleKey = typeof(WorkspaceViewModel);
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
Button closeButtonSel = base.GetTemplateChild("PART_CloseTopSelected") as Button;
Button closeButtonUnsel = base.GetTemplateChild("PART_CloseTopUnSelected") as Button;
if (closeButtonSel != null)
closeButtonSel.Click += new RoutedEventHandler(closeButtonSel_Click);
if (closeButtonUnsel != null)
closeButtonUnsel.Click += new RoutedEventHandler(closeButtonSel_Click);
//this part is causing the effect i was complaining about!
//and has to be removed
this.MouseEnter += delegate(object sender, MouseEventArgs e)
{
IsSelected = true;
};
}
void closeButtonSel_Click(object sender, RoutedEventArgs e)
{
//this is the close request method used in the CloseTabItemCommand
OnRequestClose();
}
#region CloseTabItemCommand
private RelayCommand closeTabItemCommand;
public ICommand CloseTabItemCommand
{
get
{
if (this.closeTabItemCommand == null)
this.closeTabItemCommand = new RelayCommand(p => this.OnRequestClose(), p => this.CanCloseTabItem());
return this.closeTabItemCommand;
}
}
private bool CanCloseTabItem()
{
return true;
}
public event EventHandler RequestClose;
private void OnRequestClose()
{
if (RequestClose != null)
RequestClose(this, EventArgs.Empty);
}
#endregion
}

Resources