Displayalert and userdialoges not showing in UI (Viewmodel) - xamarin.forms

In my viewmdodel class, I am calling a function from constructor. Inside of that function I am using Userdialoges and displayalert properties. But both are not showing in UI. Getting exception for both.
Displayalert Exception :
Exception:>System.NullReferenceException: Object reference not set to
an instance of an object.
UserDialogs Exception :
Exception:>System.ArgumentException: In android, you must call
UserDialogs.Init(Activity) from your first activity OR
UserDialogs.Init(App) from your custom application OR provide a
factory function to get the current top activity via
UserDialogs.Init(() => supply top activity)
I have also implemented the pull down to refresh option. When pull down I am calling the same function, but that call is not from the constructor. So when pull down UserDialoges and Displayalert are working.
My code:
UserDialogs.Instance.ShowLoading("Loading");
await Application.Current.MainPage.DisplayAlert("Alert", "No Internet Connection", "Ok");
So how can I activate the userdialoges and displayalert initially when calling the function from constructor?

Solved by comment the function call in constructor and inside of onappearing(), call the same function using the viewmodel class object(added in xaml.cs file not in viewmodel).
protected override async void OnAppearing()
{
dbvm.UserList(); //dbvm is viewmodel class object
}

Related

Xamarin Forms and IEventAggregator

Making my APP for my job I'm getting stuck on a problem:
I have a base page to fill with information for an order
1 Client
2 Destination
3 Article
When I tap on a button I get a new page (different for what I'm serching Client, Destination, Article) with a listview of the item. On a tap of the item I would like to pass the parameter to the main page to compile the order.
I think that the better solution is to implement the IEventAggregator of PRISM, I have made also some test and it work with button, but if I try to put it on the itemtapped, it give me error.
I have created the class for the event to pass the payload.
This is the xaml.cs of the page that (in theory) must pass the selected client to the mainpage:
IEventAggregator _ea;
private Cliente cliente_selezionato = new Cliente();
...
public void TapCliente(object sender, ItemTappedEventArgs e, IEventAggregator ea )
{
cliente_selezionato = (Cliente)
((ListView)sender).SelectedItem;
_ea.GetEvent<CambioClienteEvent>().Publish(cliente_selezionato);
Navigation.PushModalAsync(new DatiTestataOC());
}
On the mainpage viewmodel I have:
public DatiTestataOCViewModel(IEventAggregator ea)
{
ea.GetEvent<CambioClienteEvent>().Subscribe(NuovoCliente);
}
private void NuovoCliente(Cliente Parameter)
{
Cliente = Parameter;
}
The error that I get are:
Errore XFC0002 EventHandler "TapCliente" with correct signature not found in type "Mokadroid.Views.SceltaClientePage".
Errore XFC0004 Missing default constructor for "Mokadroid.ViewModels.DatiTestataOCViewModel".
If you have Other solution more easy to implement I'm Open...
Thanks
I've understand that I can't simply use that part of the package, I need to start a new template using the prism template and use all the package.

How can I prevent default notifications when encountering an error when using an external datasource as my datastore?

I'm building a custom content part that fetches its information from an external repository, mostly following the advice found # How to change Orchard record repository and using a custom handler to fetch the data.
Working with external data stores opens up the possibility of all sorts of network exceptions, etc., which would cause the underlying record not be saved. However, if there's an exception thrown in the ContentHandler, it's swallowed up by the Invoke<TEvents> method so that (unless it's a "fatal" exception) the user wouldn't know about the exception and would be notified by the AdminController that "Your {0} has been saved.", when in fact it hasn't been.
A workaround that's obvious to me is to intercept the error somehow and notify the content driver for my content part, which exposes the executing AdminController. At that point, I can hook into the controller's ModelState and introduce an error, which would then be caught and then I'd be notified of an error without any false positive notifications.
Are there any other extensibility points available in Orchard that would handle this kind of external access better than altering the controller's ModelState via a content driver?
The easiest way would be to implement you own, simple, per-request storage object for those errors, ie.
public interface IErrorLog : IDependency {
public void Add(string message){ ... }
public IEnumerable<string> List() { ... }
}
public class DefaultErrorLog : IErrorLog { ... }
Inject IErrorLog in both your controller and handler. In the handler, catch all errors you need to catch and add them to the collection with Add(...). Then, in the controller, call List() and add model error for each entry.
UPDATE
If you're not in control of a Controller that updates your content item, then you should use a driver. Catch the exception during item save (the second Editor method with 3 params) and push some error info using AddModelError of the provided IUpdateModel object. Way easier, but you'll be able to catch only those errors that happen when an item is saved.
UPDATE 2
If you're not in control of a Controller that updates your content item but would like to have a pure solution and gain control over the whole process, you can use your own controller for editing items. In order to do that:
create a new controller (or copy and alter the default AdminController found in Orchard.Core\Contents) first
now tell Orchard to use this controller instead of the default one for all types that contain your custom part. It can be done by putting something like this in your handler:
OnGetContentItemMetadata<MyCustomPart>((context, part) =>
{
context.Metadata.AdminRouteValues = new RouteValueDictionary
{
{ "Area", "My.Module" },
{ "Controller", "Admin" },
{ "Action", "Edit" },
{ "id", context.ContentItem.Id }
};
});

flex netconnect ( Property onTest not found on flash.net.NetConnection and there is no default value )

Having this code:
nc.call("test", new Responder(onCallSuccess,onCallFailed), "user1");
and
public function onTest(id:String):void {
Alert.show("test called from server");
}
Results in:
`ReferenceError: Error #1069: Property onTest not found on flash.net.NetConnection and there is no default value`.
How could I fix this?
Ive tried a lot of different approaches, it seems that the data is send from server application correctly but flex cannot "eat it"
You need to add nc.client = this, so the server knows where to call methods.
As I understand, onTest is callback method. Callback methods must be contained in client property of NetConnection instance. The default value for client is NetConnection instance itselft. That's why onTest is trying to be called, but it does not exist. You have 2 possible solutions here:
1.Extend NetConnection class with your custom one and define onTest method there. And use your custom class instead.
class MyNC extends NetConnection
{
public function onTest(id:String) {...}
...
}
2.Create class, which will be client for NetConnection and define onTest there.
class Client
{
public function onTest(id:String) {...}
}
...
var nc:NetConnection = new NetConnection();
nc.client = new Client();

I can't dispatch custom event from one module to another as it gives TypeError: Error #1034: Type Coercion failed:

I am trying to dispatch a custom event from one flex module to another.
The code which dispatch the event is as below
Application.application.Destination.child.dispatchEvent(
new AlgoEvent(AlgoEvent.GETFROMPARENT_LOCAL_EVENT));
here AlgoEvent is a custom event
on the other side the module which catches and handles the event has this code:
public function sendParametersToChild(e:AlgoEvent):void
{
//some codes
}
but when the statement Application.application.Destination.child.dispatchEvent(new AlgoEvent(AlgoEvent.GETFROMPARENT_LOCAL_EVENT)); is executed the debugger give the following run time exception:
TypeError: Error #1034: Type Coercion failed: cannot convert resources.events::AlgoEvent#4182239 to resources.events.AlgoEvent.
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at mx.core::UIComponent/dispatchEvent()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\UIComponent.as:9298]
at components::Destination/sendTimeToChild()[E:\FlexProjects\MyApp\src\components\Destination.mxml:99]
at components::Destination/updateParameters()[E:\FlexProjects\MyApp\src\components\Destination.mxml:206]
at components::Destination/__CreateBasketButton_click()[E:\FlexProjects\MyApp\src\components\Destination.mxml:558]
I am not able to identify what is going wrong here.
Please help to solve this problem
This is my Event class
public class AlgoEvent extends Event
{
public static const GETFROMPARENT_LOCAL_EVENT:String = "getfromparent_local";
private var eventType:String;
public function AlgoEvent(eventType:String, bubbles:Boolean=false, cancelable:Boolean=false)
{
super(eventType,bubbles,cancelable);
this.eventType=eventType;
}
}
While debugging am getting error in this funcion of UIComponent class
override public function dispatchEvent(event:Event):Boolean
{
if (dispatchEventHook != null)
dispatchEventHook(event, this);
return super.dispatchEvent(event);
}
Excaxtly this line gives the error: dispatchEventHook(event, this);
Import the AlgoEvent class in the main application and create a reference to it.
import resources.events.AlgoEvent;
private var dummyEvent: AlgoEvent;
Some explanations for this could be found here: Module domains
If your custom event doesn't carry any special event properties you could workaround your problem by using the standard Event class.
dispatchEvent(new Event(AlgoEvent.GETFROMPARENT_LOCAL_EVENT));
I had the same problem when dispatching, solved overriding two functions:
override public function clone():Event
{
return new AlgoEvent(type, bubbles, cancelable);
}
override public function toString():String
{
return formatToString("AlgoEvent","type"","bubbles","cancelable","eventPhase");
}
hope it helps out :)
Mr. splash suggested a solution which worked fro me:
Try to make the Custum Event (Algo Event in my case) class known to the main application.
I.e import it in the main application and create a variable of it..
And it works for a main reason>>when we try to communicate betwwen the modules using event dispatching what happens is :the modules are loaded at the run time but the classes like event classes are linked to the modules at the run time..
But the Event class is compiled before the modules are loaded..
application defines a Custum Event Class at compile time, and the module defines its own Custum Event Class when it is published. Then when the application is run, the Custum Event Class dispatched in the application doesn't match the one in the module
swf.
For the problem which is causing this error one can check the link:
http://www.kirupa.com/forum/showthread.php?t=320390
and also
http://www.jeffdepascale.com/index.php/flash/custom-events-in-loaded-swf-files/
Mate framework takes care of all this.
It gives you a global event bus, for all modules in your app.
http://mate.asfusion.com/
Try to override the clone() method in your customized Event,AlgoEvent.
Add the following code to your AlgoEvent.as class and try:
override public function clone():Event{
return new AlgoEvent(eventType,bubbles,cancelable);
}
HTH.
Your custom Event class should look like this:
public class AlgoEvent extends Event
{
public static const GETFROMPARENT_LOCAL_EVENT:String = "getfromparent_local";
public function AlgoEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false)
{
super(type, bubbles, cancelable);
};
override public function clone():AlgoEvent
{
return new AlgoEvent(type, bubbles, cancelable);
};
};
You should use the Event's inherited type property instead of creating a new one.
Also, the UIComponent has it's own dispatchEvent method, so you don't have to create your own - only if it works differently to the inherited one.
Regards,
Rob
Okay, it must be said that what you're doing, from an architectural standpoint, is wrong. Calling Application.application is bad for so many reason, especially if you're then starting to go down the display tree. The second any of the children changes, your build is now broke, and you won't know that until runtime because it's a module.
What you need is an application framework. A way to increase complexity without decreasing maintainability. There are many out there, but my personal favorite is Parsley. I've used it on many very large projects with much success. The problem you're trying to solve right now, dispatching one event where the other module listens for it, is extremely trivial (can be done in about 3 lines of code).
I recommend you look it over as well as my presentation on an introduction to parsley.

Passing along information on a FileReference Complete event

I need to pass along a string with my FileReference, or provide that string as an argument when an event fires. To be clear, it really annoys me that AS3 doesn't allow you to pass parameters on events.
Right now, I've extended the FileReference class to include an additional variable. I'm trying to get this to compile, but it won't compile; I think I don't know how to import this class correctly. If you can tell me how to import this class correctly so that I no longer get Error: Type was not found or was not a compile-time constant at compile time that would be great.
This is the extended FileReference class:
import flash.net.FileReference;
public class SxmFR extends FileReference {
public var housenum:String = "";
public function SxmFR(str:String) {
housenum = str;
super();
}
}
I've tried that in a .mxml and a .as in the same folder. Neither is automatically imported.
I've also tried to extend the Event class, but I couldn't figure out how to make the event dispatch, since I need to respond to the Event.COMPLETE event. If you can tell me how to make it dispatch on this, it also might work.
Please help me get this figured out, and much love and thanks to all involved. : )
If you add your event listener as a closure you have access to the variables in the current function:
function myFunction(): void {
var aParam: String = "This is a parameter";
dispatcher.addEventListener("eventName", function (e: Event): void {
// you can access aParam here
trace(aParam);
});
}
The aParam inside the function will have the same value as it had when addEventListener was called.

Resources