OnAppearing not called in prism xamarin forms - xamarin.forms

I want a process to be called each time I navigated to my view to refresh a list.
I am using Xamarin Forms and prism framework.
I made my ViewModel derivate from ContentPage but the following method is never called :
protected override void OnAppearing()
{
//Do things
}
How am I supposed to do to get the event? Is it better to use OnNavigateTo?

Through the document:
There are times in your application where you may want to invoke code
in your ViewModel based on when the Page Appears or Disappears without
Navigation specific consideration. For these times you can utilize the
IPageLifecycleAware interface to properly respond to the Appearing and
Disappearing events from the Page.
public class ViewAViewModel : IPageLifecycleAware
{
public void OnAppearing()
{
Console.WriteLine("We are appearing");
}
public void OnDisappearing()
{
Console.WriteLine("We are disappearing");
}
}

I found a solution to make my code work, I add to do this in my code behind from the page:
protected override void OnAppearing()
{
(BindingContext as IPageLifecycleAware)?.OnAppearing();
}
Still a mystery why I need to add this and it is not in the sample.

at the time of this post, the sample does it differently. It uses Behaviors to achieve expectation
It has a PageLifeCycleAwareBehavior class
private void OnAppearing(object sender, EventArgs e)
{
MvvmHelpers.InvokeViewAndViewModelAction<IPageLifecycleAware>(AssociatedObject, aware => aware.OnAppearing());
}
private void OnDisappearing(object sender, EventArgs e)
{
MvvmHelpers.InvokeViewAndViewModelAction<IPageLifecycleAware>(AssociatedObject, aware => aware.OnDisappearing());
}
You can see the full implementation here
You can also call Initialize is a good alternative
Add ini to your class
public class HelloViewModel : BindableBase, IInitialize
then add the following method
public void Initialize(INavigationParameters parameters)
{
// Do stuff
}

Related

Xamarin.Forms Cannot call OnDisappearing()

I need to just show a message (Under certain circumstance) when I'm leaving a screen.
Found that there's a method called OnDisappearing() that is called when the form is being unloaded (Or also being overlaped by a new one).
What I found:
https://forums.xamarin.com/discussion/89563/intercept-page-leaving-event
https://learn.microsoft.com/en-us/dotnet/api/xamarin.forms.page.ondisappearing?view=xamarin-forms
Issue is that if I just copy the code as it is I get an error cause of the override (no suitable method found to override) that won't let me leave the code as is:
*Same happens with OnBackButtonPressed()
Modified it and just left it without the override and it just won't be called by any mean..
protected void OnDisappearing()
{
Exiting();
}
private async void Exiting()
{
System.Threading.Tasks.Task tmpShouldExit = Application.Current.MainPage.DisplayAlert("Hello", "Hi", "OK");
}
Is something I'm missing?
Is there any other method I can use?
Thanks
As Jason made me notice.
I was placing this in the ViewModel and it has to be in the code of the View cause you're overriding a Method of the Page.
Then if you want to access a method of the ViewModel from the view you can create a BindingContext to do so:
using MyProject.PageModels;
using System;
using System.Collections.Generic;
using Xamarin.Forms;
namespace MyProject.Pages
{
public partial class MyViewPage : ContentPage
{
public MyViewPage()
{
InitializeComponent();
NavigationPage.SetBackButtonTitle(this, string.Empty);
}
protected override void OnDisappearing()
{
base.OnDisappearing();
var pageViewModel = (MyViewModel)this.BindingContext;
if(pageViewModel.CertainConditionShowAlert())
{
System.Threading.Tasks.Task tmpShouldExit = Application.Current.MainPage.DisplayAlert("Hi", "Hello", "OK");
}
}
}
}

How to link button event.click with xamarin.driod from xamarin.form

Am new to xamarin.form having a blockage...
This is what I want to do.
I have a button in welcome.xaml in xamarin.form and I want to perform a click event but I want a method from xamarin.driod to be implemented in the click.event.
Those this makes sense to anyone?
You need to write a custom control.
So you could handle the click event in the Android or IOS.
Read here about how to create a custom controls in xamarin.forms
You could also assign a static class that exist in the shared project from your driod project.
I typically prefer using IOC and Interfaces to implement platform specific logic in the Core project, but simple way to do it may just be to set a static Action on your pages code behind.
public partial class WelcomePage
{
public static Action DroidAction { get; set; }
private void Button_OnClicked(object sender, EventArgs e)
{
if (DroidAction == null)
{
Debug.WriteLine("Action was not set");
}
DroidAction?.Invoke();
}
Your Droids OnCreate could be an option of where to do this.
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
WelcomePage.DroidAction = new Action(() => Debug.WriteLine("I a platform specific action!"));
}

Event when adding a related page to a document

Apart from LogChange is there a more specific event that gets fired when adding/deleting a related page to a document ?
I want to be able to remove a page from cache when this happens
Have you tried using the global events defined by the CMS.DocumentEngine.RelationshipInfo.TYPEINFO.Events property? For example:
public class CustomRelationshipEvents : CMSLoaderAttribute
{
public override void Init()
{
RelationshipInfo.TYPEINFO.Events.Insert.After += Insert_After;
}
private void Insert_After(object sender, ObjectEventArgs e)
{
// Clear cache here
}
}
Then add your CustomRelationshipEvents attribute to an extension of Kentico's CMSModuleLoader class...

Custom Image Button control click handler not firing

I've got a bit of an issue with creating a new control based on ASP.NET's ImageButton control. Everything works as expected, except for the click handler that is being hooked up in the control's OnInit override. Basically, clicking the custom image button just refreshes the page, never hitting the handler.
Now, I know this is something stupid I've done or just not understood, but I can't for the life of me figure this out. All the articles, questions and forum posts I've found on event handling issues for controls is for child controls, rather than ones that inherit from existing control types and have their own predefined handlers.
The following code is what I've written:
public class WebPaymentButton : ImageButton
{
public string DisabledImageUrl { get; set; }
public string TermsAcceptClass { get; set; }
protected override void OnPreRender(EventArgs e)
{
Page.ClientScript.RegisterClientScriptResource(typeof (WebPaymentButton), "PaymentModule.Scripts.WebPaymentButtonScript.js");
}
protected override void OnInit(EventArgs e)
{
CssClass = "WebPaymentButton";
if (!string.IsNullOrWhiteSpace(TermsAcceptClass))
{
Attributes["data-TermsClass"] = TermsAcceptClass;
}
if (!string.IsNullOrWhiteSpace(DisabledImageUrl))
{
Attributes["data-DisabledImageUrl"] = ResolveUrl(DisabledImageUrl);
}
Click += WebPaymentButton_Click;
base.OnInit(e);
}
private void WebPaymentButton_Click(object sender, ImageClickEventArgs e)
{
HttpContext.Current.Response.Redirect("http://dummy_payment_page_in_place_of_code", true);
}
}
I've tried hooking the handler up in the OnLoad and also switching it to run after the base.OnInit/OnLoad calls. Nothing has solved the handler issue. Can anyone point me in the right direction?
In case it helps, here is the markup for the button on the page:
<pm:WebPaymentButton runat="server" ImageUrl="~/pay-now.png" DisabledImageUrl="~/not-pay-now.png" TermsAcceptClass="TermsCheckbox" ID="MainPayButton" />
Have you tried overriding the OnClick event handler instead of hooking up to a new event handler?
Remove the Click += WebPaymentButton_Click line from OnInit and remove the WebPaymentButton_Click function, then add the following code to your class instead:
protected override void OnClick(ImageClickEventArgs e)
{
base.OnClick(e);
HttpContext.Current.Response.Redirect("http://dummy_payment_page_in_place_of_code", true);
}

Separation of concerns in asp.net cause hierarchy mess

I’m designing a back office web site, one that will enable administrators to manage content, products, prices and such. I have two issues I’d like to solve in a base class that each page controller (i.e. code-behind class) will extend, and these are:
Storing of ViewState on disk, and
User validation.
Furthermore, I would like each page controller to follow the same design when it comes to setting event handlers, populating the form and saving the data. I would like to solve this issue by creating abstract methods that the page controllers implement.
Now, creating a base class that caters for ViewState storage and user validation, and furthermore defines how and when event handlers are set, forms are populated and data is persisted to me is too much of a mess. I like a high degree of separation of concerns and I’m drawn towards creating three base classes:
System.Web.UI.Page
|
FileSystemStatePage : System.Web.UI.Page
(storing of ViewState)
|
SecurePage : FileSystemStatePage
(user validation)
|
PageBase : SecurePage
(abstract, defines methods for setting event handlers, form population, saving)
Now I am quite happy with the separation of concerns, but I’m not thrilled about the deep class hierarchy. What if I find myself in the need of user validation but not ViewState on disk? So...
...how do you guys usually solve these issues?
public class FileSystemStatePage : Page
{
protected override void SavePageStateToPersistenceMedium(object viewState)
{
// Serialize ViewState...
// Save to disk...
}
protected override object LoadPageStateFromPersistenceMedium()
{
// Read file content...
// Deserialize and return...
}
}
public class SecurePage : FileSystemStatePage
{
protected override void OnInit(EventArgs e)
{
if (!ValidateUser()) Response.Redirect("~/Login.aspx");
base.OnInit(e);
}
protected virtual bool ValidateUser()
{
return LoginHelper.LoggedInSystemUser != null;
}
}
public abstract class PageBase : SecurePage
{
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
SetEventHandlers();
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
if (!IsPostBack)
{
Populate();
}
}
protected abstract void SetEventHandlers();
protected abstract void Populate();
protected abstract void OnCancel(object sender, EventArgs e);
protected abstract void OnSave(object sender, EventArgs e);
}
I'd have to say, with no particular solution, that a good separation of concerns is actually disrupted in the above nested hierarchy. It appears that the functional pieces should be further separated as to not be included every time the other is needed.
Why is it necessary that you have viewstate and validation in the same space? Why not separate it altogether?

Resources