returnedObject property - apache-flex

I'm programming in Flex Builder Burrito for an mobile application.
I'm trying to get a variable from navigator.PopView()
and i found the following site: adobe View and ViewNavigator
On that page is written that you can get to an returnedObject:
The ViewNavigator will save this object internally, and the new view can access it from with the navigator.returnedObject property.
The problem is when I want to acces the returnedObject flash builder doesn't seem to find that even the package isn't found.

I've found my problem on an other site.
There it's plain simple explained.
Do the override public function createReturnObject():Object.
On the page where it needs to be send back.
Then on the popped view, you can acces it by returnedObject.

On same page next lines are
The property is a ViewReturnObject
which contains the object that was
returned
and the context in which the removed view was pushed (See Setting
the View Context).
ViewNavigator.poppedViewReturnedObject
is guaranteed to be set by the time
the new view
receives the add event and will be destroyed after the view receives its
viewActivate
event.
and also a NOTE
Note, the return object is only stored when a view is popped of
the navigation stack
or replaced through the use of the pop and replace navigation
operations (e.g.,
replaceView, popView, etc...). It will be cleared after the new view
receives its
ViewNavigatorEvent.VIEW_ACTIVATE event.
I think should try function to get popuped view poppedViewReturnedObject of ViewNavigator
Its description is also on same page
public function get poppedViewReturnedObject():ViewReturnObject
Hopes that help

Related

Storing a view in Xamarin.Forms MvvmCross

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.

Issues with wrapping PrismForms NavigationService

In PrismForms we got the problem, that the NavigationStack is empty after navigating to a new page. That means after using the hardware back-button on the SecondPage, the app is closed. Although the back-arrow in the header on Android isnt shown. If looking closely you can see the back-arrow for a short moment after the page is switched. I guess thats before the NavigationStack gets cleared.
To the first page we navigate with the following command in OnInitialized() in our App.xaml.cs which derives from PrismApplication.
NavigationService.NavigateAsync("NavigationPage/StartPage");
(If only Navigating to „StartPage“ here, the Stack doesnt get cleared.)
That has do to with PageNavigationService.ProcessNavigationForNavigationPage(...) calling
bool clearNavStack = GetClearNavigationPageNavigationStack(currentPage); and PageNavigationService.ProcessNavigationForContentPage(...) not.
From the StartPage to the next we navigate with NavigateAsync("SecondPage")“. Here the described behaviour appears.
For navigation we use a class which wraps the Prism NavigationService. We hold him as a property and get him via Unity in our constructor:
this.PrismNavigation = prismNavigation ?? throw new ArgumentNullException(nameof(prismNavigation));
The methods „NavigateAsync“ and „GoBackAsync“, etc. we just pass through.
This way we want to seperate our ViewModel-Project from references to XamarinForms to later be able to use the same ViewModels for for example a WPF-GUI.
Why is the stack beeing cleared by our own NavigationService? If we register the original Prism NavigationService in App.xaml.cs instead, navigating back works as expected again. We found the point in the framework and could avoid the clearing with a drity hack, but that’s against the navigation-logic implemented in PrismForms, but we don’t understand how to do it the correct way.
Every help appreciated!
We edited a few things to get it working after finding some interesting information by Brian Lagunas in the forlast-post here:
https://github.com/PrismLibrary/Prism/issues/591
Although the topic was about something else, it led to improvements for overwriting the Navigation Service.
Remember that in your viewModels the Navigation Service must be named "navigationService" by convention. Also we switched from just holding the Prism Navigation Service as a parameter to deriving from it as suggested in the link above.
public class MyNavigationService : UnityPageNavigationService

Filter page datasource based on record selection

I seem to be struggling with this. I am working on a project management app in Google App Maker. I am using SQL data models. The portion of the app I am having trouble with is several project detail pages linked with a project list page. I have no trouble going from the project list page to the first project detail page.
I have a table widget in the project list page, and the onClick code for a table row is:
app.datasources.Projects.selectKey(widget.datasource.item._key);
app.showPage(app.pages.ProjectPage);
This filters the first detail page with the primary key of the record in focus. No problem here. When I want to navigate the next detail page that has a different datasource (but I still need to filter using the same primary key) I am struggling.
If someone can guide me in making a button in the first detail page that when clicked gets the _key of the project loaded in that current page and filters another detail page for the same project in focus, (using another data model, let's call it ProjectBudgetPage for example) I would really appreciate the help.
This was one my latest attempts at navigation to other detail pages within a project, this was for an onClick event:
var widgets = widget.parent.descendants;
var projectID = widgets.HiddenProjectID.text;
var projectDataSource = app.datasources.ProjectBudgetView.item;
projectDataSource = projectID;
app.showPage(app.pages.ProjectInfoPage);
which results in: (TypeError) : Cannot read property '__gwt_instance' of undefined
at HeaderProjectTabs.HeaderContainer.InfoTabButton.onClick:5:5
I am not sure if I understood properly but I suggest that you start by checking this official App Maker template available here https://developers.google.com/appmaker/templates/partner-management/ which provides a ready-to-run app you can use to manage an internal list of partners, but you can also customize it with your own needs. I recently used most of the UI and logic of this template and I was able to integrate it with SQL data models and it works really great.
I noticed that for this template they are saving the (widget.datasource.item._key) to a Page custom property which you can access afterwards. Custom properties are page-level properties that store data for a single user session. Custom properties are useful when you need to bind properties of multiple widgets to a single value. More info available here https://developers.google.com/appmaker/ui/binding#custom_properties
In your scenario, you can create a new custom property (string) inside your ProjectInfoPage and then you can add a script to the button onClick event in your ProjectPage to save the _key or any other item to a page property. For example:
app.pages.ProjectInfoPage.properties.ProjectKey = widget.datasource.item._key;
app.showDialog(app.pages.ProjectInfoPage);
Then you can get the “ProjectKey” property by adding this to the onAttach event in your ProjectInfoPage:
var key = app.pages.ProjectInfoPage.properties.ProjectKey;
…
In the onAttach event you can filter the new model or pass the property values to a server script. I believe there are other approaches but I hope this helps!

SSRS and Interactive Sorting work in MVC4

I have implemented a reporting engine in mvc using html rendering. I had to create custom paging functionality based on the metadata returned via the render method. I am now looking at implementing interactive sorting in the same fashion which is looking like a more daunting task. It seems there is a setting in the HTML Device Information Settings header for html rendering called ActionScript.
ActionScript(*)-
Specifies the name of the JavaScript function to use when an action event occurs, such as a drillthrough or bookmark click. If this parameter is specified, an action event will trigger the named JavaScript function instead of a postback to the server.
My question is has anyone used this feature? Since I lose authentication after the report is rendered I will have to somehow make authenticated callbacks in the controller. It seems to me it may be easier just to add parameters for sorting in the report, however I would like to keep the interactive sorting in the report.
--Edit Solution1---
It turns out that the * next to script name above means the ActionScript parameter is being depreciated after ssrs 2012. Thus, I decided not to pursue it. If anyone else stumbles upon this then the best way I thought of to simulate interactive sorting without post backs is detailed below:
On the Report
1. Add a parameter to the report SortField1
2. Add a Sort condition to the Tablix or group you wish to sort. Tablix-Sort Expressions
3. Set the expression of the sort to Fields(Paremeters!SortField1.Value).Value
4. Set the default value of parameter SortField1 to the default sort field
5. Set Allow Nulls of the parameter to true.
6. Add a image or label for each column you would like to sort by
7. Create a action for the element created in step 7 with code similar to
="javascript:void(reportSortRequest('ColumsFieldName'))"
NOTE: Your view or view descendant will have need to have an identical function defined to accept the action
In the View
Implement the function reportSortRequest(fieldName). This should set
Model.SortField1 and invoke the post back to the controller to
re-render the report.
In the Controller (This is for Ajax post backs that sends a model that will have a field SortField1)
Call the render with report information including SortField1.
Updated with client script that works to access the report markup wrapper.
The report element generated by the ssrs markup can be accessed in your view by its tags. I have that found the following will work using the predetermined ssrs wrapper element #oReportCell":
Loaded in iframe :
var frameContent = $("#myIFrame").contents();
var ssrsContentElement = frameContent.find("#oReportCell");
Loaded in div:
var ssrsContentElement = $("#myDiv").find("#oReportCell");
Function to load html blob into either a frame or a div. Depending how the report was configured, the content is either a url of a temp file or the html markup.
function setReportContent(content, isUrl, renderInIFrame) {
if (isUrl) {
if (renderInIFrame) {
$("#reportContent").html("<iframe id='reportFrame' sandbox='allow-same-origin allow-scripts' width='100%' height='300' scrolling='yes' onload='onReportFrameLoad();'\></iframe>");
$('#reportFrame').attr('src', content);
}
else
$("#reportContent").load(content);
}
else {
if (renderInIFrame) {
$("#reportContent").html("<iframe id='reportFrame' sandbox='allow-same-origin allow-scripts' width='100%' height='300' scrolling='yes' onload='onReportFrameLoad();'\></iframe>");
$('#reportFrame').contents().find('html').html(content);
}
else
$("#reportContent").html(content);
}
if(!renderInIFrame)
showReportWaitIndicator(false);
$("#reportContent").show();
}
Notice that if you want report images with auto-resize property set to be rendered correctly you have to turn on allow-scripts so that the ssrs resize js functions can fire, be careful.

Flex4 Right Click Spark List using ContextMenu()

I would like to add custom right clicks to a number of spark list controls.
I have tried the following as an item renderer. (as per the flex 4 cook book).
Full Render code here http://pastebin.com/Kx8tJ1cY
When I right click on the Spark List I simply get the Adobe Default Context menu.
This is the same default behaviour I had before I added any code to this.
Could anyone tell me how to add right clicks to List Items in Flex 4.
Please and Thank you.
I found the problem/solution. You cant use context menus if there are Vboxes or Tab Navigators. Which is insane because it means I cant do relative layout properly or decent variable width design.
Quoted from: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/ui/ContextMenu.html
For example, if a DataGrid control is a child of a TabNavigator or VBox container, the DataGrid control cannot have its own context menu.
Christopher Huyler posted something similar (source code available here). From the article:
Start out by grabbing the Javascript code from Google's code repository.
Step 1 – Setup custom context menu code
Create a new Flex project in Flex Builder. Copy rightclick.js and swfobject.js into the html-template folder of your project. From here, I had to make several changes…
I modified the RightClick.init() function to accept an object and container value as input. This allows me to pass in the name of the application as the object instead of having it be called the same thing every time.
I included rightclick.js and swfobject.js in the header of index.template.html.
I added a new div to the body called “flashcontent”.
I added an onload handler to the body tag to initialize RightClick
I replaced AC_FL_RunContent(…) with new SWFObject(…) making sure to maintain all template variables.
After making these changes, I verified that no right-click context menu appears in my application.
Step 2 – Listen for the rightClick event
Next I added a few lines to the main mxml file of my application to listen for the ExternalInterface event that will be dispatched when I right-click my appliction.
private function handleCreationComplete():void
{
ExternalInterface.addCallback("rightClick", handleRightClick);
}
private function handleRightClick():void
{
Alert.show("Right Click Success!");
}
Step 3 – Dispatch an event to the correct object
Getting the event to the main application is easy, but we actually want the appropriate child object to be notified when the right-click event occurs. Since I am not using any double-click events in my application I decided I would treat every right-click event like a double-click event. Users without a two button mouse (aka Mac users) can simply double-click to get the same menu while users with a two button mouse just have to right-click. Here is how I make sure the event is dispatched to the appropriate object.
private function handleRightClick():void
{
var objects:Array = systemManager.getObjectsUnderPoint(
new Point(mouseX,mouseY));
if (objects.length>0)
{
var object:Object = objects[objects.length-1];
var relatedObject:InteractiveObject;
if (object is InteractiveObject)
relatedObject = object as InteractiveObject;
else if (object.parent && object.parent is InteractiveObject)
relatedObject = object.parent;
var event:MouseEvent = new MouseEvent(
MouseEvent.DOUBLE_CLICK,true,false,mouseX,mouseY,
relatedObject);
object.dispatchEvent(event);
}
}
I hope this helps!

Resources