I know about tombstoning stuff any how to save the states of your application but my question is this regarding states.
Let's say I have a page that have 5 buttons. Whenever I click a button the button can be either visible or hidden. How do I save the current state or the saved state of my page? Let's say if I exit my application and loaded the 5 buttons again one button should be hidden.
I tried saving a variable state value in an IsolatedStorageFile and retrieve it when the Page is loaded in loaded event but I figured out that it's too tedious for the processor to do a lot of things just for saving a state.
Another solution I thought of is when the Loaded event is fired, I will statically declare an if else statements and manually declare the Visibility of the button.
Is there any other way?
Are you trying to do the same thing when the page/app is exited normally and when it's tombstoned? The default expected behaviour is that when launching the app after exiting (via the back button) the app will be in it's default state. When returning from a tombstoned state the app should (as far as is appropriate) be displayed to the user in exactly the same way as when the page/app was tombstoned.
Of course you may have differing needs but I wanted highlight the standard behaviour.
If you want to store state while tombstoned, the convention is to use the OnNavigatedFrom and OnNavigatedTo events to store details in the State object.
There is a good example of how to do this on MSDN: How to: Preserve and Restore Page State for Windows Phone
If you want to preserve state across all executions of your app then you will need to use IsolatedStorage to store the details in a persistent location. Where and when you read and write the data will depend on where the data you need to persist is located.
If it's at an applicaiton level you may be able to use the application level events (Launching, Activated, Closing & Deactivated). If you have state data at page level it's probably be better to do it in the page level (Loaded/Unloaded or NavigatedFrom/To as appropriate).
If you want to store state across all executions of the application you probably need to look at both of the above options.
The System.IO.IsolatedStorage namespace is fine for this kind of behaviour, check it out here
Also check out this article on how to do what you are asking.
Saving Applications States
Related
I am writing an Xamarin Forms application using MVVM Cross. I'm using the Master-Detail presentation model.
I'm attempting to wire up my application to support tombstoning. To do so, I configured my android device so that Don't Keep Activities = true. This has the correct desired affect in that when I switch to another application, my application activities are destroyed and when I switch back my application reloads.
However, the methods SaveStateToBundle are never called and subsequently, ReloadFromBundle is never called. So, I'm stuck on finding a way for my application to restore itself in the tombstoning workflow.
Has anyone had any success doing this? Complicating matters is that I not only want to remember the state of my detail page, but i also need to remember which detail page was actually loaded. But at this point I haven't found any way to save my state in the first place.
thanks to all who can help!
Michael
I have an application that contains multiple MemoEdit controls containing DevExpress spell checkers. When a user updates the Options (through a MemoEdit's context menu), we are saving those options to our db. Is there any built-in way to broadcast those new options to all spell checkers in the application? It's probably worth noting that some of the MemoEdits are used in Interop controls in the VB6 "part" of our application.
Right now I'm using events, but things aren't working out as well as I'd hoped and before I get too deeply into rolling my own fix I figured I'd ask the SO folks.
Thanks in advance for any tips.
My tech lead and I just acquired dev express subscription for a win forms application we are building and we are using the spellchecker and saving the options to our sql server ce table. We have multiple forms with one spellchecker each tied to one memo edit control per form.
I programmed a single reusable function named “GetSpellCheckerOptions” which returns type “DevExpress.ExtraSpellChecker.OptionsSpelling” that loads the six options from the spell check options dialog form from our sql server ce table. This function is invoked in a form’s constructor where the form has the spellchecker component associated to it and this can be any form in our application. It is built around an “on-demand” basis as opposed to loading it in memory and keeping it around for the lifetime of the application because the notes or comments being written by our users are on forms that load, fill it out and close.
You can use the event called OptionsChanged which is a member of the type “DevExpress.ExtraSpellChecker.OptionsSpelling”. You will have hook up the event in runtime using a subroutine you write like this for example:
jobsSpellChecker.OptionsSpelling.OptionChanged += new EventHandler(this.jobsSpellChecker_OptionChanged);
When a user changes an option on the spell check options dialog this event will fire, however there are some gotchas to be aware of. When the event fires you will not know which option fired the event because the Event Argument does not provide that information. So I save as a whole save regardless of which options were changed. The save occurs after the OK button is clicked as opposed per option being changed. The biggest gotcha is that this event fires three times. Two of those three times is from something totally unrelated to changing an option. So to control the two unneed event fires you need an if statement evaluating the options form dialog result, like this for example,
if(jobsSpellChecker.FormsManager.OptionsForm.DialogResult == System.Windows.Forms.DialogResult.OK)
This will protect your save code from being executed needlessly. In addition without the “if” statement the control has a nasty way of remembering previous state of what the options were before you changed them and during those unneeded two of three event fires, it changes your options setting from the new desired settings back to previous state or settings. Very annoying and it has taken the whole day to get past these obstacles and more experimenting with these controls. Hopefully this information can offer you or someone else a value that will save time, avoid potential frustration and endless browsing product support pages.
I'm looking for some ideas as I'm trying to wrap my head around the best way to code menu navigation with one interrupt driven device. In particular a rotary encoder knob with a push button. The question is how to manage how the interrupt routines will change depending on the context of the menu/dislay. Also, what data types should I used to keep track of the menu etc.
I'm programming an embedded device with the NetMF framework in C#. The rotary encoder know will fire an interrupt/event when it's rotated and return the direction and timestamp. Also, the push button will fire another interrupt/event and return the timestamp.
A simple outline. Device will boot up and start in some default state. Then the user can rotate the knob to change the "mode". This is simple, to me. Now, when it comes to the user controlling the settings, It would be something like press and hold the momentary for 3 seconds. After 3 seconds it will switch into settings mode. Now, the rotary encoder will rotate through different settings. Scroll/rotate to the setting you want. Forwards or backwards. Then, press the button to enable editing the setting...again, change what the rotary encoder and button do. Maybe press and hold button for exit and save all settings. Menus may be nested.
Thinking aloud:
Hardware Functions are Change-Setting-To-Edit(rotate), Enter specific Setting/forward/deeper into menu(button), Change Setting Value(rotate), Save Setting(button), Go-Back(button), Save-All and exit to Main Mode.
Each Setting "Page" or display could have a forward and back indicator that can be selected with the Rotary encoder.
Anyway it flows, I'm looking for a way to keep track of the menus and the controls of the rotary encoder and so that it's easy to extend and read.
How do I manage all of the different functions of the Interrupt Event Handlers as I change menu contexts? Is there some way to have have a set of functions for each context? How Do I keep track of them?
Thanks!
REVISED BETTER QUESTION:
How to pass native event handler for interrupt in state pattern code
What you are describing is a classic example of an event-driven state machine -- the events are handled differently depending on the current context (i.e. state). Check out QP for a framework that could suit you well. Or if that requires too much of an investment then Google for more traditional ways of implementing a state machine.
I have a settings save method I call, but I tried unload, and lost focus the application will close out and not save before ever getting to either of those methods. When should I save application settings to keep this from happening?
Should I use a timer and save every 30 seconds, or what?
How often you save depends on your app. However, the key timings are:
Launching
Activated
Deactivated
Closing
Launching is called when the app is first launched from the main screen and Closing is called when the user presses the back key to exit your app. Naturally, you'll most likely want to save permanent data in the Closing event.
Activated is called when the user has closed your app via the Windows button and has gone back into it by pressing the back button. This doesn't get called if the user launches the app for the first time.
Likewise, the Deactivated event is called when the user presses the Windows button. Depending on your app, you'll want to save transient data at this point so that when it's restored, you can give the illusion that your app wasn't closed at all. (Otherwise, for example, all textboxes will become empty even if the user entered data before pressing the Windows button).
Those are the main events, so you can design your app around that. One thing to remember is that if your save files are going to be big, and they take longer than 10 seconds to save after the closing event is called, your app will be terminated immediately, possible corrupting the save file. Therefore, for large saves files, you should plan ahead by saving incrementally (for example, after the user has made a change that should remain permanent).
There's no one size fits all solution to this as saving timings are highly dependant on the type of app being developed. Have a read of the Execution Model MSDN Page as it goes into more detail and provides code examples.
Here is a sample from MSDN on how to implement settings page for Windows Phone.
http://msdn.microsoft.com/en-us/library/ff769510(v=vs.92).aspx
Msdn doc for IsolatedStorageFile.IncreaseQuotaTo states that:
To increase the quota, you must call
this method from a user-initiated
event, such as in an event handler for
a button-click event. When you call
the IncreaseQuotaTo method, the common
language runtime in Silverlight
presents a dialog box for the user to
approve the request. If the user
declines the request, this method
returns false and the quota remains
the same size.
How does Silverlight know that the method was called from a user-initiated event like a button click and not from some other thread?
More specifically: What is a user initiated event? Is there any way to overcome this limitation?
And another question:
I do some automatic downloads of files when user first accesses my application, but I don't want the user to press "Download" and then when I detect more space is needed call IncreaseQuota and have the "Silverlight dialog" appearing asking for more space.
I want to start the download automatically (not user initiated), and if I detect more space is needed, call IncreaseQuota and hence have the "Silverlight dialog" appear. (No user pressing download).
After much digging, I did find out what a user initiated event is. Seems that msdn doc specifies what a user initiated event in the section related to "events overview", but there's no link between documentation of IsolatedStorageFile.IncreaseQuotaTo and Events Overview
So a user initiated event according to the definition is:
Silverlight enforces that certain
operations are only permitted in the
context of a handler that handles a
user-initiated event. The following is
a list of such operations:
Setting IsFullScreen.
Showing certain dialogs. This includes
SaveFileDialog, OpenFileDialog, and
the print dialog displayed by
PrintDocument.Print.
Navigating from a HyperlinkButton.
Accessing the primary Clipboard API.
Silverlight user-initiated events
include the mouse events (such as
MouseLeftButtonDown), and the keyboard
events (such as KeyDown). Events of
controls that are based on such events
(such as Click) are also considered
user-initiated.
API calls that require user initiation
should be called as soon as possible
in an event handler. This is because
the Silverlight user initiation
concept also requires that the calls
occur within a certain time window
after the event occurrence. In
Silverlight 4, this time window is
approximately one second.
User-initiated event restrictions also
apply to usages of JavaScript API for
Silverlight.
When Silverlight is in full-screen
mode, some input events are
deliberately limited for security
reasons, although this can be
mitigated for out-of-browser
applications using elevated trust. For
more information, see Full-Screen
Support.
Although I don't see "IncreaseQuotaTo" inside the list of "operations", I'm guessing they just forgot it, since the behavior/limitations are the same as the ones described in the doc.
I was curios how exactly does silverlight know what a user initiated event is but after digging through .net framework source code I've got to a dead end:
if ((browserService == null) || !browserService.InPrivateMode())
{
//..
}
return false; //means that IncreaseQuota will fail
where browser.IsInPrivateMode is:
[SecuritySafeCritical]
public bool InPrivateMode()
{
bool privateMode = false;
return (NativeMethods.SUCCEEDED(UnsafeNativeMethods.DOM_InPrivateMode(this._browserServiceHandle, out privateMode)) && privateMode);
}
where DOM_InPrivateMode is in a DllImport["agcore"] which according to microsoft is confidential :(
So it looks like I won't find out soon how they're detecting user initiated events.
Thinking it more about it, I guess microsoft didn't want a user to have many tabs open in a browser and then poof: I call automatically IncreaseQuotaTo.
The IncreaseQuotaTo is a browser modal dialog. This means you can't navigate to other browser tabs while is active.
So if the user has now moved from my page to the tab with google.com, and if I would be able to call IncreaseQuotaTo with a delay, the user might think that google.com is asking for more storage :).
This would be a security breach indeed.
Had they implemented this with a page level dialog, then that would have been probably more easily hacked (or worked around).
So all in all, thinking of it, I'm starting to see why they implemented it like this and why these limitations exist.
The documentation isn't incomplete.
If I do this... button_click(..) { new UserControl() }... Does this still count as a user initiated event?
Yes. But what has that little bit of extra code really achieved?
What i've personally never experimented with is exactly what consitutes a user event; IOW is a mouse-over considered a user event? This will be very simple for you to try, and there are a multitude of other things you can experiment with. If necessary you could have a splash screen popup that welcomes the user and they have to click on it to dismiss it, at which point you make the request. It may seem a bit corny, but you can get away with things like this if you present it well.
Note that the prompt is a one-time thing. If you prompt the user and they accept, that storage is persisted for your application between visits, which means you don't need to prompt them again the next time they use your control, your quota is still increased from last time (unless the user has deliberately deleted it, which they can do by right clicking on the Silverlight control and then going to the Application Storage tab).