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
Related
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);
}
}
}
}
I'm using this well documented solution to add a back button to our app. I'm setting things up like this when the App is initialized:
Windows.UI.Core.SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility = AppViewBackButtonVisibility.Visible;
Windows.UI.Core.SystemNavigationManager.GetForCurrentView().BackRequested += CreateNewKeyView_BackRequested;
private void CreateNewKeyView_BackRequested(object sender, BackRequestedEventArgs e)
{
NavigationService.Instance.GoBack();
}
The back button is shown on the desktop app and works as expected, navigating our Frame back to previous pages.
However, on Windows Phone, the hardware button just exits the app. The various places that I found code like this all state that this should work for the mobile hardware button, but it simply isn't working for us.
You should set e.Handled = true in your CreateNewKeyView_BackRequested method.
Don't know how you code for your NavigationService, I just tested the following code, it works by my side:
private void CreateNewKeyView_BackRequested(object sender, BackRequestedEventArgs e)
{
Frame rootFrame = Window.Current.Content as Frame;
if (rootFrame != null)
{
if (rootFrame.CanGoBack)
{
e.Handled = true;
rootFrame.GoBack();
}
}
}
Or, for a phone, we use also special API for Hardware Buttons.
You can judge if the current using a phone Api is or not in the OnLaunched method:
if (Windows.Foundation.Metadata.ApiInformation.IsTypePresent("Windows.Phone.UI.Input.HardwareButtons"))
{
Windows.Phone.UI.Input.HardwareButtons.BackPressed += OnBackPressed;
}
then complete the OnBackPressed method:
public void OnBackPressed(object sender, Windows.Phone.UI.Input.BackPressedEventArgs e)
{
Frame rootFrame = Window.Current.Content as Frame;
if (rootFrame != null)
{
if (rootFrame.CanGoBack)
{
e.Handled = true;
rootFrame.GoBack();
}
}
}
To do this, you need at first add the Windows Mobile Extensions for the UWP references in your project.
Here is
private void CreateNewKeyView_BackRequested(object sender, BackRequestedEventArgs e) //event handle nya untuk backbutton
{
var frame = ((Frame)Window.Current.Content);
if (frame.CanGoBack)
{
frame.GoBack();
e.Handled = true;
}
}
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;
}
}`
I have had a problem where on some instances in the emulator, when I click the back hardware button the back page loads with the constructor being called and some other time the constructor is not called.Why is this? Is this because its the emulator?
How are you performing navigation? Are you canceling the initial OnNavigatingFrom in order to perform an animation, then listening initiating navigation again after the animation completes?
protected override void OnNavigatingFrom(System.Windows.Navigation.NavigatingCancelEventArgs e)
{
if (_pendingNavigation == null)
{
VisualStateManager.GoToState(this, "LeavingPage", true);
_pendingNavigation = e.Uri;
e.Cancel = true;
}
base.OnNavigatingFrom(e);
}
void LeavingPage_Completed(object sender, EventArgs e)
{
var uri = _pendingNavigation;
NavigationService.Navigate(uri);
_pendingNavigation = null;
}
The bug occurs when you call NavigationService.Navigate(), which then adds a new page instance to the navigation stack. To fix this bug, you need to check and make sure the initial page navigation is a "New" navigation. Something like so:
if (e.NavigationMode == NavigationMode.New && _pendingNavigation == null)
{
VisualStateManager.GoToState(this, "LeavingPage", true);
_pendingNavigation = e.Uri;
e.Cancel = true;
}
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
}