In my Xamarin.Forms application, I have 1 page and am setting the view model in the xaml as such:
<ContentPage.BindingContext>
<vm:MainViewModel />
</ContentPage.BindingContext>
The problem is, that when I put the app in the background and then open it again, I have 2 instances of MainViewModel. I can see with the debugger that a new one is created, but also code from the first one (before I put it in the background) is still being called (from event handlers).
How can I fix this? Is it possible to retain and use the same view model? Or am I forced to have a new one every time I close and reopen the app? If so, how do I make sure the old one is released from memory?
I'm running the app on an Android device.
This sounds like a regression bug, since it was reported/fixed multiple times.
I have a similar thread here on SO : Xamarin.Forms ViewModelLocator get called twice
Don't set the BindingContext in XAML unless it is a one page app, instead consider using an IoC container.
Related
I have a very simple Flex application for mobile phones which uses 3 tabs (with the TabbedViewNavigatorApplication).
It seems that everytime I switch tabs, the selected view is reloaded.
I've set a creationComplete command to do something and everytime I click on the tab it executes the function.
Isn't it possible for the views to get loaded 1 time and that's it?
Seems to me that this behaviour is exactly the point on mobile devices since you want to keep memory / cpu usage as low as possible.
This effectively means destroying all non-active views and all related view components / objects.
However you can override this default behaviour by setting the destructionPolicy on every view to destructionPolicy="never".
This blog post will explain the basic understanding you will need to obtain.
Cheers
I'm trying to implement a popup window (NativeWindowType.UTILITY) in an AIR 2.7 application that uses Swiz for dependency injection.
I have followed the Swiz guidelines that I've been able to find, and implemented ISwizAware on the class that creates the window, and I am calling _swiz.registerWindow() before opening the window, and dependency injection works fine on the window itself after this.
However, the problem I am running into is that I have a child view within that window, and I have a mediator that uses the [ViewAdded] and [ViewRemoved] tags. Neither the view added nor view removed functions are triggering. I'm thinking the issue is either:
The child view is not correctly registering with Swiz.
The swiz instance doesn't know about the beans (I have tried manually adding the bean however, which didn't have any effect).
The ViewAdded and ViewRemoved metadata tags simply aren't working because each NativeWindow object has its own stage instance.
Anyone know more about this?
Popups are a special case since they don't get added under the same display tree as your application. Under Stage (the main wrapper for Flash Player), you'll have Application where your code resides for Swiz, but Popup is in a separate layer above Application. Since they're siblings, Swiz cannot listen in for when the popup is being added to the Stage.
The way around this is to either set the properties of the popup manually (which is normally the easiest way) or manually add the popup to Swiz's awareness. For this you'll have to look at the documentation since I haven't touched Swiz in a long time.
ok so I have a TitleWindow that I open up... and I have 6 states defined. I am using the Presentation model pattern for all of my views. I have discovered a frustrating nuance. When I tell my window to go to XXX state, the controls have to initialize since the states in flex use lazy loading. so... my PM code that says myTextArea.text bombs out and say "cannot access..." so as a work around, I made some creationComplete events on my controls to register the control with the PM. So when the state changes, the textarea finally initializes and on creationComplete calls PM.registerTextArea() which sets a reference to it. then in that function I run my code... myTextArea.text.. etc.
This seems like such a ugly hack that I hate it. Is there any way to wait until the entire state in created then call code on the PM? I have tried enterstate... but this event seems to fire before the state controls are ready.
I tried to add a comment, but I guess editing is the only way I can do this...
to everyone: thanks for the great feedback. I am doing something slightly off straight PM. Every view has a viewController (as I call them). Its kinda my own hybrid of a delegate / dataprovider. But this is moot. It's the flex component lifecycle when dealing with states that is the pain. if you change state.. there is no event to say "all my components in this state are ready". only event to say "we changed state". so my code that fires on state change is trying to talk to components that aren't ready yet. So from what I see, there seems to be no design pattern or perfect way to ensure that all components are created in a state unless using creationComplete on every component in the state to register it is ready... if you don't, you get a race condition. Regardless of frameworks or design patterns, this seems to be a root issue.
The textarea is an easy PM fix.. just bind it to the pm value. But there are other times I can't.
Specifically, I am trying to attach video to a display once I get to that state. This is done via addchild. regardless of where I do it.. I need to know that the videoDisplay is done loading before I call addchild. I even tried currentStateChange event since docs say that fires last... but alas.. the components in the state are still initializing. So it seems that creationComplete is my only option. Maybe the only sane way to keep to clean code is to create the entire thing (videodisplay and video) using as once the state is entered. I just hoped the flex framework had events to ehlp me here rather than buiilding everything on the fly in as.
Since your PM has a reference to a visual component (myTextArea), this isn't a completely pure form of a presentation model. It appears to be more of a supervising presenter / controller type of setup.
That being said, the way I would fix your problem would be to use a complete presenter outright ( no knowlege of the view at all ) or use a complete controller ( view implements an interface through which the controller communicates ). The advantage of using a presenter in Flex is that you can create a bindable value such as text or selectedItem, and the view will bind to that variable whenever it comes online so the issues dealing with the lifecycle of Flex components go away.
I would like to know the correct way to close an AIR application programmatically.
In my Spark WindowedApplication I have:
this.addEventListener( Event.CLOSING, shutdownApp );
and of course an implementation of the shutdownApp method (which basically tidies up temporary files).
This works fine for the top-right close button of the window. However I also have functionality which needs to shutdown the application. Within the code I have called:
NativeApplication.nativeApplication.exit();
However this doesn't trigger the Event.CLOSING method, and so my temporary files are not cleared up. Should I not be calling nativeApplication.exit ? If so, what should I call instead? I'd rather not have to call my shutdownApp method before the NativeApplication.exit() as this doesn't feel quite so elegant.
Can anyone shed any light on the correct way of doing this?
Thanks,
Phil
I know this question has been answered and accepted, but thought I'd share, I use.
stage.nativeWindow.close();
The documentation looks a bit ambiguous on this and I would have the same interpretation that you did. Did you try the close or exit methods on the WindowedApplication?
Something like this, with FlexGlobals and topLevelApplication:
(FlexGlobals.topLevelApplication as WindowedApplication).close();
or
(FlexGlobals.topLevelApplication as WindowedApplication).exit();
Just give an answer here because I searched for a related question and was not able to find sth.
I wanted to do something similar and close an AIR application when the native close button of the document window (spark.components.Window) is pressed thought that the spark WindowedApplication container (the applications main window) is still active to hold and manage the native menu (at application startup it is also used to display a splash screen. It has to stay open since if it is closed the native menu won't show up or be accessible anymore so its visible property is just set to false).
My main problem was the window closing event. Registering it with ActionScript like
this.addEventListener(Event.Closing, windowClosed);
does not work: No closing event was dispatched.
The only way was to register an event handler directly in the s:Window element at start of the MXML file. I just throw in the closing attribute:
closing="window1_closingHandler(event)"
The event was dispatched then and in window1_closingHandler-function I called
NativeApplication.nativeApplication.exit();
That works for me and shuts down the whole application.
When I try to access the hidden TABs of my tab navigator control in action script, it returns a null error. But it works OK if I just activate the control in the user interface once. Obviously the control is not created until I use it. How do I make all the tabs automatically created by default ?
<mx:TabNavigator creationPolicy="all"/>
That should do it. Deferred instanciation is a feature, but sometimes it is a hassle.
The Flex framework is optimizing creation be default (creationPolicy="auto") so if you have a configuration dialog with a lot of tabs, for example, and the most useful tab is the first one, your application does not spend time and memory initializing the tabs that the user never sees.
This makes a lot of difference when dialogs like this never release, and is a good default to go with.
One thing to look at is using a private variable in your dialog/form instead of pushing the data to the control on the hidden page. This style treats the whole form as if it were a component, which it sort of is. To repeat: the MXML form/dialog/canvas is a class, and it can have data and methods in addition to containing other components.
Cheers
On a side note, I've run into the deferred-loading policy in a multi-state application, and circumvented it by forcing all elements to be included and invisible in the initial state. Something to consider, but only as a hack.