Anyone know if it is possible in a WF4 native activity to schedule a dynamically created child activity? The activity accepts args that determine the child activity to instantiate and run. I've been running into CacheMetadata issues.
Not possible but you could use the InvokeWorkflow / LoadActivity support I built into Microsoft.Activities. See How To Invoke a Child Workflow as XAML
The workflow runtime must know what Activities you are going to run before execution. So you cannot do the following:
protected override void Execute(NativeActivityContext context)
{
context.ScheduleActivity(new MyActivity());
}
Unfortunately, the same goes for the Handler of an ActivityAction or ActivityFunc. These must also be set and presented to the runtime during a call to CacheMetadata.
The only possible solution is to implement IActivityTemplateFactory and provide some implementation to your child activity at design time when it is dropped on the design surface, and possibly update your child during calls to CacheMetadata by examining the current workflow and responding accordingly before registering the child with the runtime.
Related
I have an app with four main pages, switched through a tab bar (no "back" button).
One page has a lot of content (ScrollView) and takes quite a few seconds until it's rendered. I handle that by showing a "loading" overlay while the work is done. But for that specific page I'd like to keep the view alive, so that when the user switches to another page and comes back later, the page is ready without loading everything again.
I'm not sure how to do that in MvvmCross, though.
I did read the documentation and from what I understood the View Presenter would be the right way to do it, since the docs say:
"Another kind of presentation changes your app can request through
hints includes clearing / modifying the BackStack, changing a root
while maintaining the existent views, … possibilities are really
endless. Once again your app is king here!"
I guess I would need to create a custom MvxPresentationHint for that, but I don't quite get it :(
How or rather where would I access and store/load the View?
I'm generally still quite unfamiliar with MvvmCross (how it works under the hood) and especially customization of Mvx classes, even though I've been using it for a while.
Any explanation and preferably code examples beyond what's written in the documentation would be extremely appreciated!
It isn't meaningful to attempt to "store" a view in MVVM. The XF view is a representation of what will be created with native (e.g. "Android" or "iOS") widgets. Creating and measuring/laying out those native widgets is what is slow. MVVM View Presenter won't speed up that logic.
Instead of "store", you need "keep alive":
For a ContentPage called MyPage, when you create it, store it in a static variable. Then re-use that variable. If you never need more than one of these, you can store it in the class itself.
Modify the "code behind", MyPage.xaml.cs:
public partial class MyPage : ContentPage
{
// Singleton Pattern.
private static MyPage _it;
public static MyPage It {
get {
if (_it == null)
_it = new MyPage();
return _it;
}
}
// "private", because calling this directly defeats the purpose. Instead, use `MyPage.It`.
private MyPage()
{
InitializeComponent();
}
}
To create it, whereever you would put:
new MyPage()
instead put this:
MyPage.It
For instance, you might do PushAsync(MyPage.It);
This will always return the SAME INSTANCE of MyPage. So once it has been created, it keeps its state.
IMPORTANT: Note that the constructor is only called ONCE. Any code that needs to be done each time the page appears, put in override .. OnAppearing() method.
LIMITATION: Views "expect" to be part of the visual hierarchy when they are manipulated. If you attempt to alter the page or its view model while it is not on the screen, you may encounter problems. Those are beyond the scope of this answer - create a new StackOverflow question with the details of any problem you encounter.
I am wondering if all asynchronous events and callbacks can be traced back to a specific source component by wrapping all component logic (including logic of non-component directives inside component) in a zone, then only that source component needs to be checked for changes along with any child components with changed inputs from the source component, assuming all changes are following the uni-directional flow.
Is this understanding sound?
Is this change detection strategy available in Angular2?
Why is Angular2 detecting changes on all the components after any asynchronous (XHR) event?
One whole Angular application runs in a single zone. Angular uses the zone to patch async APIs and uses notifications from these patched APIs to run change detection every time some async event happened.
The uni-directional flow is for [prop]="value" bindings that works only from parent to child.
Angular runs change detection from root to leafs.
If ChangeDetectionStrategy.OnPush is configured for a component, change detection skips these components (and their descendants) until some binding (inputs) have changed.
There are other strategies to optimize CD.
For example observables and promises, that actively notify about changes and don't need change detection.
Immutable objects which are guaranteed to not change their propery values.
Update
Angular doesn't know what values an event handler has changed. Properties of a component, of a global service, of object references that were passed around, .... It just assumes that when an event handler was called that probably something has changed and then runs a complete change detection cycle to propagate all bindings from parent to child.
Child do parent bindings are events anyway and therefore aren't updated during change detection.
... by wrapping all component logic (including logic of non-component directives inside component) in a zone, then only that source component needs to be checked for changes along with any child components with changed inputs from the source component, assuming all changes are following the uni-directional flow. Is this understanding sound?
When an template-bound event fires – e.g., (click)="doSomething()" – the doSomething() method is free to alter any component or application data. Template statements, such as our doSomething() event handler, are not bound by the unidirectional flow rule, as per the Angular docs:
Responding to events is the other side of Angular's "unidirectional data flow". We're free to change anything, anywhere, during this turn of the event loop.
This is why, by default, Angular's change detection has to check every template binding in every component after an event fires. (Well, after an event within the Angular zone fires.) Angular doesn't know what might have changed... it has to discover what has changed.
The unidirectional flow rule applies to template expressions such as {{some expression}} or [childInputProperty]="parent expression" or if you implement an input property setter method: #Input() set childInputProperty(variableName:type) { ... }.
Is this change detection strategy available in Angular2?
No, because it would severely limit what an event handler could do. Dirty-checking every template binding may not be the most efficient way to detect changes, but it makes it much easier for us to write our event handlers (i.e., to write our applications).
Why is Angular2 detecting changes on all the components after any asynchronous (XHR) event?
Angular doesn't want to limit what we can do in our event handlers. An event handler bound in ComponentA's template can change data that is local to ComponentA, but it can also change data that is in a service (and hence it can change data that is visible to other components), and it can change data in other components, e.g., by calling public APIs/methods on other components.
Below is the overriden on complete function for a preloader in Flex.
private function initComplete(e:Event):void
{
//dispatchEvent(new Event(Event.COMPLETE));
cp.status.text="Configuring... Please Wait";
}
What I want to do is when the app has finsihed loading I want to change the preloaders text to "configuring".
Then I want to go and do a bunch of setup stuff in my code.
Once I've done all the setup I wanted how can I get the Preloader to dispatch its Event.complete from else where in my code?
I tried Application.application.preloader but it comes up null.
So I guess my question really is how to access a preloader from anywhere in my application.
Would a better approach be to have all setup classes as members of my preloader class?
One thing that might help is a Model-View-Controller pattern. Are you using a framework for your application like Mate, Swiz, or Cairngorm?
If you were using Mate, for example, you could do something like this:
Create an AppStateManager class with a property (e.g. applicationState)
Create an EventMap with an EventHandler for the FlexEvent.INITIALIZE event. In this handler, set the AppStateManager.applicationState to something like "CONFIGURING"
Your EventMap has an injector that injects the applicationState property into a view. The injector listens for changes to this property and updates the view. In this case it might just be injected into your main view.
In the main view, you have a public bindable property also called applicationState that gets injected by Mate.
In the setter for this property, you can have an if/then or a switch that does different tasks depending on the state. For example, if applicationState == "COMPLETE", then this.preloader.dispatchEvent(Event.COMPLETE) or something like that.
The details are pseudo-sketched out but the idea is to use Flex's bindings to notify view components when changes have been made, and to have shared objects that maintain state. Not sure if that's what you're looking for...
The component LifeCycle does specific stuff in a specific order, and the near final element is to make the component visible.
It sounds to me like you want to defer this setting of visible to true to do other stuff. But, I imaging if you were making use of the component LifeCycle this would be a non-issue.
What sort of app init stuff do you need to do?
I have a TitleWindow mxml class wich has several components, and listeners.
On its creationComplete and init state i add some listeners which listen for events on its gui.
This TitleWindow is only shown when the user click on a "button", i made TitleWindow a singleton with the following code:
public static function getInstance():MyWindow
{
if ( MyWindow.singleton )
{
return MyWindow.singleton;
}
else{
MyWindow.singleton = new MyWindow();
return MyWindow.singleton;
}
}
I needed a singleton because the user will call this window several times as much as he wants and i only need one.
The problem is the following on some special external events i need to "modify" some listeners (remove listeners and add new ones) on a button from MyWindow, before it was even shown once.
I still have MyWindow.getInstance() in memory when my application starts up.
However adding /removing listeners does not seem to have any effect if he actual rendering of the components did not happen, event when using the following code on app startup.
myWindow= MyWindow.getInstance();
myWindow.initialize();
Not suprisingly if i "show" ('render') the myWindow at least once then the events modifications on the myWindow instance works perfectly.
How can i fake the complete initialisation of this component without showing it on startup ?
Thanks !
Which sort of a container holds your button? If you are using a Multiple View Container you can try setting the creationPolicy to all. Single View Containers create all their children in one go and you shouldn't face this problem.
From Flex 3.0 docs I could retrieve this:
The default creation policy for all containers, except the Application container, is the policy of the parent container. The default policy for the Application container is auto.
This looks like the cause for all your troubles.
Update: I did not mention this earlier, since I thought this was to be expected :) Setting the creationPolicy to all makes your application load more slowly. So, read up on Ordered Creation -- this technique helps you to choose if the controls are displayed all in one go (which is the default behavior, after all of the controls have been created) or step-by-step, as and when they are created.
I am working on a small AIR desktop application and I have some configuration infos that I want to store in a little file that's loaded at some point when the application starts and will be used to set public properties on the root application object. This should work just as if I had public variables declared in an <mx:Script> block at the beginning of my main MXML file.
I seem to have the choice of three events that could be used to initiate loading the configuration file:
invoke
initialize
creationComplete
Did I overlook some more? Which one is appropriate and why? Does it matter at all?
Example issues that come to my mind are:
are all components already accessible or will I get NULL references?
will some of my settings be overwritten in a phase that's coming after the event?
There's probably more.
If your handler needs to access UI components directly, you should wait for creationComplete; otherwise you'll get NULL references.
If you simply want to set properties on the root Application object, initialize seems the best place to do this. If you wait until creationComplete, and if the properties that you set are bound to your controls, then you might get a run-time resize or flicker as those components are updated.