Stop users going from one page to another page - windows-8.1

I want to stop users going from one frame/page back to the main previous page.
For example, when the user successfully logs in they are to go to the users list page.
If a user presses the hardware back button from the users list page, then they shouldn't go back to the login screen. If they do, the program should either prompt with two buttons, yes to logout and go back to the login screen, or no and stay on the current screen.
private void HardwareButtons_BackPressed(object sender, Windows.Phone.UI.Input.BackPressedEventArgs e)
{
Frame frame = Window.Current.Content as Frame;
if (frame == null) return;
//the current frame is UserList
if (frame.Content is UserList)
{
messageBox("yes");
e.Handled = true;
}
else if (frame.CanGoBack)
{
frame.GoBack();
e.Handled = true;
}
}
In theory, if the current frame is the user list page, then do not go back.
How can I stop a user from going back a page?

First you need to attach the event to HardwareButtons back button which is available in Windows.UI.Xaml.Input namespace. Add this below InitializeComponent call in page constructor.
HardwareButtons.BackPressed += HardwareButtons_BackPressed;
If you just handle the event it is enough to prevent user from going back with hardware back button.
private void HardwareButtons_BackPressed(object sender, BackPressedEventArgs e)
{
e.Handled = true;
}
If you don't want to allow the user to go back if the previous page is Login page you can try this.
private void HardwareButtons_BackPressed(object sender, BackPressedEventArgs e)
{
e.Handled = true;
if (Frame.BackStack.Last().SourcePageType.Equals(typeof(LoginPage)))
{
//TODO: handle prompt
} else {
Frame.GoBack();
}
}
ps: if you handle e you should provide Frame.GoBack(); manually otherwise users will be stuck in that page.

Related

How to Scroll pdfView automatically with button click or volume buttons

I'm using barteksc pdf viewer library to load pdf in my application.
pdfView = findViewById(R.id.pdfView);
pdfView.fromAsset(getResources().getString(R.string.pdfname))
.enableDoubletap(true)
.enableSwipe(true)
.defaultPage(pageNumber)
.onPageChange(mainreading.this)
.pageFitPolicy(FitPolicy.WIDTH)
.pageFling(true)
.linkHandler(null)
.enableAnnotationRendering(true)
.swipeHorizontal(true)
.scrollHandle(new DefaultScrollHandlenew(mainreading.this))
.enableAntialiasing(true)
.load();
}
I want pdf to start scroll automatically when user click the button of volume up and down buttons to start stop. I tried with below code while wrapping it in the handler with handler.performClick(); but it shows blank screen while scrolling up and down.
scrollbutton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
pdfView.scrollTo(0, pdfView.getScrollY() + 24);
}
});
Example :
https://play.google.com/store/apps/details?id=com.emptysheet.pdfreader_autoscroll&hl=en&gl=US
I want to make as like this. Can anyone help please.
Also tried with this. But it shows blank page after some scrolls.
#Override
public boolean dispatchKeyEvent(KeyEvent event) {
int action = event.getAction();
int keyCode = event.getKeyCode();
switch (keyCode) {
case KeyEvent.KEYCODE_VOLUME_UP:
if (action == KeyEvent.ACTION_DOWN) {
pdfView.scrollTo(0, pdfView.getScrollY() -24);
}
return true;
case KeyEvent.KEYCODE_VOLUME_DOWN:
if (action == KeyEvent.ACTION_DOWN) {
pdfView.scrollTo(0, pdfView.getScrollY() + 24);
}
return true;
default:
return super.dispatchKeyEvent(event);
}
}
You can simply use this PDF viewer from github.
It's based on the same 'barsteksc' pdf viewer with the feature to jump to any pages.
It's MagicalPdfViewer and you can use 'jumpTo(pageNo)' method to simply jump to the specific page. It also gives you the option to animate to the specific page with the same method, just pass 'true' as the 2nd parameter.
Moreover, if you pass the values like '-1' and 'bigger than pageNo', It will automatically scroll to the 0 & last page respectively.
Give it a try & let me know if you got what you wanted.

Cannot trigger cancel button action after processing results returned

Within the Acumatica 19.201.0070 framework I have created a custom processing page that utilizes PXFilteredProcessing with the old style processing UI public override bool IsProcessing => false; I have defined a cancel button (below) that will clear the graph and set some values of the processing filter.
public PXCancel<NPMasterSubGeneratorFilter> Cancel;
[PXCancelButton()]
protected virtual IEnumerable cancel(PXAdapter adapter)
{
NPMasterSubGeneratorFilter row = Filter.Current;
if (row != null)
{
this.Clear();
Filter.SetValueExt<NPMasterSubGeneratorFilter.segmentID>(Filter.Current, row.SegmentID);
if (!(row.NewSegment ?? false)) Filter.SetValueExt<NPMasterSubGeneratorFilter.segmentValue>(Filter.Current, row.SegmentValue);
}
return adapter.Get();
}
This works perfectly fine except for a single use case, after processing results are shown if the user then presses the cancel button the corresponding action is never hit. ( My fellow office devs state that core Acumatica processing pages seem to operate the same. )
Setting of the processing delegate is within the filter RowSelected event.
GeneratedSubs.SetProcessDelegate(list => CreateSubaccounts(list, row));
I have implemented a few iterations of my processing method but the current is below.
protected virtual void CreateSubaccounts(List<NPGeneratedSub> subs, NPMasterSubGeneratorFilter filter)
{
if (filter.NewSegment ?? false)
{
try
{
SegmentMaint segGraph = PXGraph.CreateInstance<SegmentMaint>();
segGraph.Segment.Update(segGraph.Segment.Search<Segment.dimensionID, Segment.segmentID>(AADimension.Subaccount, filter.SegmentID.Value));
SegmentValue value = segGraph.Values.Insert(new SegmentValue() { Value = filter.SegmentValue, Descr = filter.Description });
segGraph.Actions.PressSave();
}
catch
{
throw new PXOperationCompletedSingleErrorException(NonProfitPlusMessages.SegmentValueCannotCreate);
}
}
SubAccountMaint subGraph = PXGraph.CreateInstance<SubAccountMaint>();
NPSubAccountMaintExtension subGraphExt = subGraph.GetExtension<NPSubAccountMaintExtension>();
subGraphExt.save.ConfirmSaving = false;
Sub newSub;
bool errored = false;
foreach (NPGeneratedSub sub in subs)
{
PXProcessing<NPGeneratedSub>.SetCurrentItem(sub);
try
{
newSub = subGraph.SubRecords.Insert(new Sub() { SubCD = sub.SubCD, Description = sub.Description });
subGraph.Save.Press();
subGraph.Clear();
PXProcessing<NPGeneratedSub>.SetProcessed();
}
catch (Exception e)
{
PXProcessing<NPGeneratedSub>.SetError(e);
errored = true;
}
}
if (errored)
{
throw new PXOperationCompletedWithErrorException();
}
}
What needs to be adjusted to allow the buttons action to be triggered on press after processing results have been returned?
After stepping through the javascript I discovered that it wasn't sending a request to the server when you click the cancel button on this screen after processing. The reason is because SuppressActions is getting set to true on the Cancel PXToolBarButton. I compared what I was seeing on this screen to what was happening on screens that work correctly and realized that Acumatica is supposed to set SuppressActions to true on the Schedule drop down PXToolBarButton but for some reason, on this screen, it is incorrectly setting it to true on whatever button is after the Schedule drop down button.
I looked through the code in PX.Web.UI and it looks like they set SuppressActions to true when a drop down button is disabled and PXProcessing adds a FieldSelecting event to the Schedule button which disables the button after you click process. However, I didn't notice any obvious issues as to why the code would be setting it on the wrong PXToolBarButton so someone will likely need to debug the code and see what's going on (we are unable to debug code in PX.Web.UI.dll).
I tried commenting out the other grids in the aspx file that aren't related to the PXProcessing view and this resolved the issue. So my guess would be that having multiple grids on the PXProcessing screen somehow causes a bug where it sets SuppressActions on the wrong PXToolBarButton. However, since the multiple grids are a business requirement, removing them is not a solution. Instead, I would suggest moving all buttons that are after the schedule button to be before the schedule button. To do this, just declare the PXActions before the PXFilteredProcessing view in the graph.
Please try this
Override IsDirty property
Use PXAction instead of PXCancel
Add PXUIField attribute with enable rights
action name should start from lowercase letter
delegate name should start from uppercase letter
see code below
public override bool IsDirty => false;
public override bool IsProcessing
{
get { return false;}
set { }
}
public PXAction<NPMasterSubGeneratorFilter> cancel;
[PXUIField(MapEnableRights = PXCacheRights.Select)]
[PXCancelButton]
protected virtual IEnumerable Cancel(PXAdapter adapter)
{
NPMasterSubGeneratorFilter row = Filter.Current;
if (row != null)
{
this.Clear();
Filter.SetValueExt<NPMasterSubGeneratorFilter.segmentID>(Filter.Current, row.SegmentID);
if (!(row.NewSegment ?? false)) Filter.SetValueExt<NPMasterSubGeneratorFilter.segmentValue>(Filter.Current, row.SegmentValue);
}
return adapter.Get();
}

UWP page state manage

I want to learn how to manage the state of a page between navigation.
for example a navigate onto page1 and then i navigate to page2, but when i navigate back to page1, the UI elements must already be there with the same data as before and they must not be re-initialized or data must not be binded again by the compiler.
Also what I can do to manage state of whole application such that, I terminate the app and then when i launch it next time, the same state is already there as last time. can i apply it on whole application? or what if I only want to apply it on a few pages? any help would be appreciated thanks.
or example a navigate onto page1 and then i navigate to page2, but when i navigate back to page1, the UI elements must already be there with the same data as before and they must not be re-initialized or data must not be binded again by the compiler.
For this question, you may use UIElement.CacheMode property and Frame.CacheSize property. CacheSize property sets the number of pages in the navigation history that can be cached for the frame, and CacheMode property sets a value that indicates that rendered content should be cached as a composited bitmap when possible.
As we know, an UWP app default using a rootFrame for displaying several pages, we just use Navigation method to change the content in the frame. You can see this in the OnLaunched(LaunchActivatedEventArgs e) method of a blank UWP app. But how to implement cache function? For example, your app has two page and one root frame. You can define CacheSize property in your OnLaunched(LaunchActivatedEventArgs e) method for example:
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
...
// Ensure the current window is active
rootFrame.CacheSize = 2;
Window.Current.Activate();
}
Then in your two pages's constructed functions enable CacheMode property for example:
public MainPage()
{
this.InitializeComponent();
this.NavigationCacheMode = NavigationCacheMode.Enabled;
}
Also what I can do to manage state of whole application such that, I terminate the app and then when i launch it next time, the same state is already there as last time. can i apply it on whole application?
For this question, you will need to save the page state in the OnSuspending(object sender, SuspendingEventArgs e) method using Frame.GetNavigationState method, and you can save this state into the app's local settings. For example:
private void OnSuspending(object sender, SuspendingEventArgs e)
{
var deferral = e.SuspendingOperation.GetDeferral();
Frame rootFrame = Window.Current.Content as Frame;
string navstate = rootFrame.GetNavigationState();
var localSettings = ApplicationData.Current.LocalSettings;
localSettings.Values["nav"] = navstate;
deferral.Complete();
}
And how to retrieve this informaton? You can override your OnLaunched(LaunchActivatedEventArgs e) method, and at first you will need to judge how is your app be closed last time, by user, or by system using ApplicationExecutionState enumeration, for example like this:
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
//#if DEBUG
// if (System.Diagnostics.Debugger.IsAttached)
// {
// this.DebugSettings.EnableFrameRateCounter = true;
// }
//#endif
Frame rootFrame = Window.Current.Content as Frame;
// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
if (rootFrame == null)
{
// Create a Frame to act as the navigation context and navigate to the first page
rootFrame = new Frame();
rootFrame.NavigationFailed += OnNavigationFailed;
if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
{
//TODO: Load state from previously suspended application
}
// Place the frame in the current Window
Window.Current.Content = rootFrame;
}
if (rootFrame.Content == null)
{
// When the navigation stack isn't restored navigate to the first page,
// configuring the new page by passing required information as a navigation
// parameter
//rootFrame.Navigate(typeof(MainPage), e.Arguments);
if (e.PreviousExecutionState == ApplicationExecutionState.Terminated ||
e.PreviousExecutionState == ApplicationExecutionState.ClosedByUser)
{
object value;
var localSettings = ApplicationData.Current.LocalSettings;
if (localSettings.Values.TryGetValue("nav", out value))
{
rootFrame.SetNavigationState(value as string);
}
else
{
rootFrame.Navigate(typeof(MainPage), e.Arguments);
}
}
else
{
rootFrame.Navigate(typeof(MainPage), e.Arguments);
}
}
// Ensure the current window is active
rootFrame.CacheSize = 2;
Window.Current.Activate();
}
But be aware that when an app is closed, next time you launch this app, the UI elements will be re-initialized, this function can only navigate to the page when the last time you close your app, but the data in that page will be lost. But you can also save the data to the local settings and when you navigate to the page, set the value to those UI elements.

How can identify Mouse Click event in PreTranslateMessage?

I want identify all mouse click event in PreTranslateMessage, but when I use WM_LBUTTONDOWN than WM_LBUTTONDBLCLK portion never called. Please tell me how can I identify all events separately.
This code will get the mouse click events in PreTranslateMessage
BOOL CSampleDlg::PreTranslateMessage(MSG* pMsg)
{
if(pMsg->message == WM_LBUTTONDOWN)
{
//add ur customized code here...
return false;
}
return CDHtmlDialog::preTranslateMessage(pMsg);
}

Login control's loggedin event not firing

I've noticed that forums are littered with examples of this problem, but with the only solutions referring to events not actually being hooked up, or typos. I'm pretty sure that my problem relates to neither of these!
I have a login control with an opening tag that looks like this:
<asp:Login ID="signInControl" FailureText="Sorry, your login has not been successful" runat="server" DisplayRememberMe="false" OnLoggedIn="signInControl_LoggedIn" OnAuthenticate="signInControl_Authenticate" OnLoggingIn="signInControl_LoggingIn">
Here are my events in the code-behind:
protected void signInControl_LoggedIn(object sender, EventArgs e)
{
MembershipProvider provider = Membership.Providers[GlobalConstants.MembershipProviderName];
MembershipUser user = provider.GetUser(this.signInControl.UserName, true);
int expiryInDays = Utility.GetConfigurationValueAsInt(SPContext.Current.Web, "PasswordExpiryLengthInDays");
// provide a mechanism to stop password expiry (i.e. if -1);
if (expiryInDays > 0)
{
expiryInDays = expiryInDays * -1;
// If the user hasn't changed their password within the last x days, send them to update it.
DateTime minimumPasswordChange = DateTime.Now.AddDays(expiryInDays);
TimeSpan due = user.LastPasswordChangedDate.Subtract(minimumPasswordChange);
Logging.LogTrace(string.Format("The user {0} next password change is in {1} days.", user.UserName, due.Days));
if (user.LastPasswordChangedDate >= minimumPasswordChange)
{
SPUtility.Redirect("/_layouts/ExpiredPassword.aspx", SPRedirectFlags.Trusted, this.Context);
}
}
else
{
SPUtility.Redirect("/_layouts/ExpiredPassword.aspx", SPRedirectFlags.Trusted, this.Context);
}
}
protected void signInControl_Authenticate(object sender, AuthenticateEventArgs e)
{
SPClaimsUtility.AuthenticateFormsUser(new Uri(SPContext.Current.Web.Url), this.signInControl.UserName, this.signInControl.Password);
e.Authenticated = Membership.ValidateUser(this.signInControl.UserName, this.signInControl.Password);
}
protected void signInControl_LoggingIn(object sender, LoginCancelEventArgs e)
{
Logging.LogTrace(string.Format("User {0} attempting to sign in.", this.signInControl.UserName));
e.Cancel = false;
}
And as you can see in the authenticate event, e.authenticated is being set by whether the user can be validated. I've confirmed by stepping into the code that true is returned. So why isn't my signInControl_LoggedIn method firing? I'm seriously confused!
This is the markup for the front-end:
Thanks for any help!
Karl.
There are number of posts that describe how to create your own custom login page for SharePoint 2010. Here is the one I followed. In general, they create an application page that inherits from FormsSignInPage. For a page that just needs to change the look and feel, this works well. In some cases, like this one, creating the login page in this way may not be enough.
The way it is described at the end of this post, you need to inherit from IdentityModelSignInPageBase instead of FormsSignInPage. You also need to create an event handler for the authenticate event and register this in the OnLoad event of the page.
This is because the Authenticate method in the control will automatically take the user to the "ReturnUrl" page before it ever calls the OnLoggedIn event. It only takes two lines of code to authenticate the user in this method.
void signInControl_Authenticate(object sender, AuthenticateEventArgs e)
{
Login signInControl = sender as Login;
e.Authenticated = SPClaimsUtility.AuthenticateFormsUser(this.Page.Request.Url, signInControl.UserName, signInControl.Password);
}
Since your code now does not send the user to the ReturnUrl value, the OnLoggedIn event is reached.
You may ask why do I need the OnLoggedIn event if I have to create a custom Authenticate method. Well, there are still functions the control will handle for you. For instance, if the user does not authenticate (ie bad UN and PW combination), the control will display the error message and the OnLoggedIn never fires.
If you inherit from FormsSignInPage you may override your function RedirectToSuccessUrl:
protected override void RedirectToSuccessUrl()
{
//Your code here if successful login
base.RedirectToSuccessUrl();
}

Resources