I am rewriting a code base from MVVMLight to Prism. I have an interface IDispatchOnUIThread that I am implementing in iOS.
What is the equivalent of MVVMLight's DispatchHelper in Prism ?
using MyApp.Model;
using GalaSoft.MvvmLight.Threading;
using System;
namespace MyApp.iOS
{
public class DispatchOnUIThread : IDispatchOnUIThread
{
public void Invoke(Action action)
{
DispatcherHelper.CheckBeginInvokeOnUI(action);
}
}
}
To my knowledge, there is no such thing in the Prism lib. Maybe cause Xamarin.Forms offers it out of the box: Device.BeginInvokeOnMainThread.
So you could go:
namespace MyApp.iOS
{
public class DispatchOnUIThread : IDispatchOnUIThread
{
public void Invoke(Action action)
{
Device.BeginInvokeOnMainThread(action);
}
}
}
Related
I'm trying to port an Android existing custom ViewRenderer to iOS.
I'm using version 4.8 of Xamarin.Forms.
Specifically, I need to match Android's OnAttachedToWindow & OnDetachedFromWindow.
The Android Code is like the following:
public partial class HybridWebViewRenderer : ViewRenderer<HybridWebView, Android.Webkit.WebView>
{
protected override void OnAttachedToWindow()
{
base.OnAttachedToWindow();
...
}
protected override void OnDetachedFromWindow()
{
base.OnDetachedFromWindow();
...
}
}
According to this link, I would need to override ViewWillAppear which is the iOS equivalent to OnAttachedToWindow.
The custom Renderer for iOS is the following:
public partial class HybridWebViewRenderer : ViewRenderer<HybridWebView, WkWebViewRenderer>, IWKScriptMessageHandler
{
}
But the overrides are not available.
How can I do that?
ViewWillAppear and ViewWillDisappear are the life cycle method of UIViewController.So you could create the custom renderer of ContentPage
in the ContentPage that contains the WebView
using Foundation;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
using App1;
using App1.iOS;
[assembly:ExportRenderer(typeof(MainPage),typeof(MyPageRenderer))]
namespace App1.iOS
{
public class MyPageRenderer:PageRenderer
{
public override void ViewWillAppear(bool animated)
{
base.ViewWillAppear(animated);
MessagingCenter.Send<Object,UIViewController>(this,"ViewWillAppear",this); // send message when the method been called .
}
public override void ViewWillDisappear(bool animated)
{
base.ViewWillDisappear(animated);
MessagingCenter.Send<Object, UIViewController>(this, "ViewWillDisappear", this);
}
}
}
in WebViewRenderer
Subscribe the message in the constructor .
MessagingCenter.Subscribe<Object, UIViewController > (this, "ViewWillDisappear",(arg,controller)=> {
// controller is the current UIViewController
});
I'm trying to make dependency on UWP by this tutorial https://www.mvvmcross.com/documentation/platform/uwp/universal-windows-platform-uwp?scroll=621
but on this step in Setup.cs:
public Setup( Frame rootFrame ) : base( rootFrame ){}
I get an error
does anybody have an idea why??
Dependency on Android works well
Solution
App.xaml.cs
public partial class App
{
public App()
{
InitializeComponent();
}
}
public abstract class AWSService : MvxApplication<Setup, Core.App>
{ }
Setup.cs
public class Setup : MvxWindowsSetup<Core.App>
{
public Setup()
{ }
protected override IMvxApplication CreateApp()
{
Mvx.IoCProvider.RegisterType<IYourInterface, YourNativeClass>();
return new Core.App();
}
}
I'm trying to learn more about .Net Core and Castle dependency injection and inversion of control, but I just can't find neither UseLog4Net in LoggingFacility, while implementing my CompositionRoot, nor FromThisAssembly in Classes while implementing my installers. What am I doing wrong?
CompositionRoot.cs
using Castle.Facilities.Logging;
using Castle.Windsor;
namespace PitchulaBeerNBurger.POS.CrossCuttingConcerns.DependencyInjection
{
public class CompositionRoot
{
public virtual void ComposeApplication(IWindsorContainer container)
{
container.AddFacility<LoggingFacility>(f => f.UseLog4Net());
container.Install(
new Installers.CrossCuttingConcerns(),
new Installers.Persistence(),
new Installers.Domain(),
new Installers.Business()
);
}
}
}
DomainInstaller.css
using Castle.MicroKernel.Registration;
using Castle.MicroKernel.SubSystems.Configuration;
using Castle.Windsor;
namespace PitchulaBeerNBurger.POS.CrossCuttingConcerns.Installers
{
public class Domain : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(Classes.FromThisAssembly()
.Where(type => type.Name.EndsWith("Factory"))
.LifestyleSingleton());
}
}
}
NuGet packages installed:
Castle.Core.4.3.1
Castle.Core-log4net.4.3.1
Castle.LoggingFacility
There are some pages in the App,Some pages are portrait,but some pages are landscape.
If using android native code,i can do it like this:
<activity
android:name=".activity1"
android:screenOrientation="landscape" />
<activity
android:name=".activity2"
android:screenOrientation="portrait"/>
But how to define different screen orientation in xamarin.forms
You can Achieve this making a Dependency
Make an interface in your Main Forms Project:
namespace Example
{
public interface IOrientationHandler
{
void ForceLandscape();
void ForcePortrait();
}
}
Call it like:
DependencyService.Get<IOrientationHandler>().ForceLandscape();
DependencyService.Get<IOrientationHandler>().ForcePortrait();
Android
[assembly: Xamarin.Forms.Dependency(typeof(OrientationHandler))]
namespace Example
{
public class OrientationHandler : IOrientationHandler
{
public void ForceLandscape()
{
((Activity)Forms.Context).RequestedOrientation = ScreenOrientation.Landscape;
}
public void ForcePortrait()
{
((Activity)Forms.Context).RequestedOrientation = ScreenOrientation.Portrait;
}
}
}
iOS
[assembly: Xamarin.Forms.Dependency(typeof(OrientationHandlerImplementation))]
namespace Example
{
public class OrientationHandlerImplementation : IOrientationHandler
{
public void ForceLandscape()
{
UIDevice.CurrentDevice.SetValueForKey(new NSNumber((int)UIInterfaceOrientation.LandscapeLeft), new NSString("orientation"));
}
public void ForcePortrait()
{
UIDevice.CurrentDevice.SetValueForKey(new NSNumber((int)UIInterfaceOrientation.Portrait), new NSString("orientation"));
}
}
}
I want to call a base.Dispose() on the OnDisappearing() from my Android project in Xamarin.Forms.
I have done something like this :-
namespace Project.Mobile.Droid
{
[assembly: ExportRenderer(typeof(ItemListPage), typeof(DisposeRenderer))]
class DisposeRenderer : ViewRenderer
{
public DisposeRenderer() { }
}
}
How can I go ahead with this?
Iam new to Xamarin.Forms, so it would be a great help if someone helps me on this.
As long as your ItemListPage implements IDisposable, you could try the following :-
using System;
using DisposableControlSample;
using DisposableControlSample.Droid;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(DisposablePage), typeof(DisposablePageRenderer))]
namespace DisposableControlSample.Droid
{
public class DisposablePageRenderer : PageRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Page> e)
{
base.OnElementChanged(e);
e.NewElement.Disappearing += (sender, args) =>
{
var disposablePage = sender as IDisposable;
if (disposablePage != null)
{
disposablePage.Dispose();
}
};
}
}
}