Initialize method not getting called on GoBackAsync, Xamarin forms - ios

The question can be really basic since I have little to no knowledge about Xamarin Forms.
I have recently started working on an old Xamarin Forms project where I had to upgrade "Prism.Plugin.Popups" plugin to Version="7.2.0.1046"
and “Prism.Unity.Forms" to Version="7.2.0.1422"
I had to Implement IInitialize Interface since INavigatingAware is deprecated in latest Prism framework as mentioned in https://github.com/PrismLibrary/Prism/issues/1858
Issue:
I want app to navigate back from XPopupPage to AViewModel with the code _navigationService.GoBackAsync(navParams); which is working but Initialize function of AViewModel isn’t getting called once it comes back from XPopupPage.
Here’s the code:
AViewModel:
public class AViewModel : BindableBase, INavigationAware, IInitialize {
....
// Code to navigate to XPopupPageViewModel private void ShowPopup(object obj)
{
_navigation.NavigateAsync($”{.....}”);
}
//NOT GETTING CALLED once it come back from XPopupPageViewModel
public void Initialize(INavigationParameters parameters) {
.....
} }
XPopupPageViewModel:
public class XPopupPageViewModel : BindableBase, INavigationAware, IInitialize
{
//Code to navigate back to AViewModel private void Update(object obj)
{
....
var navParams = new NavigationParameters(.....); _navigationService.GoBackAsync(navParams);
} }

From the github issue you posted:
Use OnNavigatedTo when calling GoBack

Related

Gluon Afterburner Presenter.initialize() not called

Link to repository: https://gitlab.com/RichardGladman/medimindr
I've created a new Multiple view with Afterburner project using the IntelliJ plugin and added a new view to the project. It displays some about information as I thought it would be easy. The view displays just fine with the exception that the AboutPresenter doesn't get initialised meaning the AppBar is not populated.
The presenter class
package com.thefifthcontinent.medimindr.views;
... imports snipped ...
public class AboutPresenter extends GluonPresenter<MediMindr> {
#FXML
private View about;
public void initialize() {
about.showingProperty().addListener((obs, oldValue, newValue) -> {
if (newValue) {
AppBar appBar = getApp().getAppBar();
appBar.setNavIcon(MaterialDesignIcon.MENU.button(e ->
getApp().getDrawer().open()));
appBar.setTitleText("About");
}
});
}
}
The creation in the AppViewManager
public static final AppView ABOUT_VIEW = view(
bundle.getString("drawer.about"),
AboutPresenter.class,
MaterialDesignIcon.DASHBOARD,
SHOW_IN_DRAWER);
I can't see a difference between what I have done and what was created with the project.
It turns out they are still configured in the pom.xml. I thought it would be auto injection using Afterburner.

How to get the instance of an injected dependency, by its type using Umbraco.Core.Composing (Umbraco 8)

I need to find a way to get an instance of DataProcessingEngine without calling it's constractor.
I am trying to find a way to do so using the registered DataProcessingEngine in composition object (please see the following code). But I could not find a way to do so.
Anyone have a suggestion? Thanks in advance.
public class Composer : IUserComposer
{
public void Compose(Composition composition)
{
composition.Register<IDataProcessingEngine, DataProcessingEngine>(Lifetime.Singleton);
//DataProcessingEngine dataProcessing = compostion.Resolve<IDataProcessingEngine>()??//no resolve function exists in Umbraco.Core.Composing
SaveImagesThread(dataProcessingEngine);
}
public Task SaveImagesThread(IDataProcessingEngine dataProcessingEngine)//TODO - decide async
{
string dataTimerTime = WebConfig.SaveProductsDataTimer;
double time = GetTimeForTimer(dataTimerTime);
if (time > 0)
{
var aTimer = new System.Timers.Timer(time);
aTimer.Elapsed += new ElapsedEventHandler(dataProcessingEngine.SaveImages);
aTimer.Start();
}
return default;
}
}
For all of you who are looking for a way to call a function (that's defined in another class in your code, an Engine or ...) from the composer(where the app starts) and want to avoid calling this function's class' constractor. I've found another way to do so:
public class QueuePollingHandler
{
[RuntimeLevel(MinLevel = RuntimeLevel.Run)]
public class SubscribeToQueuePollingHandlerComponentComposer :
ComponentComposer<SubscribeToQueuePollingHandler>
{ }
public class SubscribeToQueuePollingHandler : IComponent
{
private readonly IDataProcessingEngine _dataProcessingEngine;
public SubscribeToQueuePollingHandler(IDataProcessingEngine
dataProcessingEngine)
{
_dataProcessingEngine = dataProcessingEngine;
SaveImagesThread(_dataProcessingEngine);
}
public void SaveImagesThread(IDataProcessingEngine
dataProcessingEngine)
{
....
}
}
And the logic explenation: You create a class (SubscribeToQueuePollingHandlerComponentComposer from the example) and define its base class to be ComponentComposer<Class_that_inherits_IComponent>.
And when you start the application you could see that it gets to the registered class' constractor (SubscribeToQueuePollingHandler constructor).
That's the way that I found to be able to call a function right when the application starts without needing to call its class constractor and actualy use dependency injection.

Cannot implement YouTube Android Player API with Mvvm Model xamarin

I need to use YouTubePlayerView to play Youtube Video in my mvvm crossplatform project. The problem is: my view needs to inherit 2 classes while C# does not allow multiple inheritance:
VideoDetailView.cs
public class VideoDetailView : MvxAppCompatActivity, YouTubeBaseActivity
{
}
YouTubeBaseActivity to use Google Player API, to use a YouTubePlayerView, your activity must extend YouTubeBaseActivity.
MvxAppCompatActivity to be able to bind View with ViewModel.
Have been stuck in this issue for couple days, I need help!
Thanks
To implement this feature, you can create MvxYouTubeBaseActivity:
MvxYouTubeBaseActivity : YouTubeBaseActivity, IMvxEventSourceActivity, IMvxAndroidView
{
protected MvxYouTubeBaseActivity()
{
BindingContext = new MvxAndroidBindingContext(this, this);
this.AddEventListeners();
}
//Implement all methods from IMvxEventSourceActivity, IMvxAndroidView
}
And create MvxYouTubeBaseActivity<TViewModel.>:
public abstract class MvxYouTubeBaseActivity<TViewModel>: MvxYouTubeBaseActivity, IMvxAndroidView<TViewModel>
where TViewModel : class, IMvxViewModel
{
protected MvxYouTubeBaseActivity(IntPtr ptr, JniHandleOwnership ownership)
: base(ptr, ownership)
{
}
protected MvxYouTubeBaseActivity()
{
}
public new TViewModel ViewModel
{
get => (TViewModel)base.ViewModel;
set => base.ViewModel = value;
}
}
That's all, you can use it with MVVMCross

Call WebView page method from referenced WinRT Component with AllowForWeb class

I have a XAML page with WebView inside (for example MainPage.xaml). Also I have WinRT Component with class marked with [AllowForWeb] attribute. This component is referenced from project where MainPage.xaml located and in code-behind AddWebAllowedObject method is used. And I can't reference main project back because of circular dependency.
How to call MainPage.xaml.cs methods from component class? Very usual situation. Is there are some standard way to do it?
For example. I have a method inside RT component that could be called from JavaScript
public void ShowMessage(string message)
{
// I want to call here function from MainPage.xaml.cs
}
How to call MainPage.xaml.cs methods from component class? Very usual situation. Is there are some standard way to do it?
Yes, you can pass the method from MainPage.xaml.cs to Windows Runtime Component through delegate(Currently it's very limited to use delegate in Runtime Component using C#, see this case, so I use C++ as demo).
For Runtime Component Class MyClass.h:
public delegate Platform::String^ MyFunc(int a, int b);
public ref class MyClass sealed
{
public:
MyClass();
static Platform::String^ MyMethod(MyFunc^ func)
{
Platform::String^ abc=func(4, 5);
return abc;
}
};
And you can use the delegate in code behind like below:
using MyComponentCpp;
private void myBtn_Click(object sender, RoutedEventArgs e)
{
String abc=MyClass.MyMethod(MyMethod);
myTb.Text = abc;
}
private String MyMethod(int a, int b)
{
return (a.ToString() + b.ToString());//replace this line with your own logic.
}
And here is the complete Demo: TestProject.
Thankfully to #Elvis Xia who has gived me idea, I has found a solution how to do it without C++.
I have create a third project as Class Library. It doesn't has restrictions to use Action. This library I have referenced from main project and from WinRT component. Code of class inside library:
public class BridgeClass
{
public static event Action<string> MessageReceived;
public static void Broadcast(string message)
{
if (MessageReceived != null) MessageReceived(message);
}
}
Code inside main project with webview is:
// place somewhere
BridgeClass.MessageReceived += ShowMessage;
// ....... and add a method
void ShowMessage(string msg)
{
}
And now i can call this code from WinRT component:
public void ShowMessage(string message)
{
BridgeClass.Broadcast("lalala");
}

Auto registering complex generic types in StructureMap

I need some help in auto-registering generics using StructureMap. Here is my scenario:
public class Object<T>
{
}
public interface IBehvior<T>
{
void DoSomething(T t);
}
public class Behvior<T> : IBehvior<Object<T>>
{
public void DoSomething(Object<T> t)
{
}
}
What I want to accomplish is something like:
var x = ObjectFactory.GetInstance<IBehavior<Object<int>>();
But when I run this statement, it gives me an error that no default instance is configured. In my StructureMap configuration I've used
ConnectImplementationsToTypesClosing(typeof(IBehavior<>))
But it still doesn't work!
Note that this worked fine if I didn't have Object. For example, if I have:
public class IntBehavior : IBehavior<int>
{
}
Everything works perfectly fine. But when I replace int with a generic type, it doesn't work!
Any ideas?
Ok I discovered the solution here:
http://lostechies.com/jimmybogard/2010/01/07/advanced-structuremap-custom-registration-conventions-for-partially-closed-types/

Resources