Shell BackButtonBehavior command binding not working in UWP - xamarin

I am kind of new to Xamarin development. I tried to change the back button behavior with a binding command, but that didn't seem to work. This is the code for the view:
<Shell.BackButtonBehavior>
<BackButtonBehavior Command="{Binding GoBack}"/>
</Shell.BackButtonBehavior>
And this is the code for the view model:
public CreatePasswordVM()
{
_goBack = new Command(GoBackButton);
}
private ICommand _goBack;
public ICommand GoBack
{
get { return _goBack; }
}
public async void GoBackButton()
{
await Shell.Current.GoToAsync("../..");
}
When I pressed the back button, the method "GoBackButton" didn't call. I want to mention that on Android works.

Shell BackButtonBehavior command binding not working in UWP
Derive from Xamarin Form source code. BackButtonBehavior has not implemented for UWP platform, we could find Android and IOS implementation here and here. But for uwp there is not such tracker and there is not such value in the UWP ShellRenderer. For this scenario, we suggest your post new feature request in the Xamarin Forms github.

Related

How can I set up my application main page (shell) from the OnAppearing of a login page with Xamarin Forms?

I have an application that I added a launch page to in the iOS and Android code. However when the app starts there is still quite a long delay while it fetches data. At this time there's a blank screen where I assume the app is still setting up the constructor.
I am trying to have an in-between page where that appears that loads the data. Not sure if this is the best way to do this but so far it's all that I have.
Here's the code that I have so far:
public App()
{
InitializeComponent;
MainPage = new NavigationPage(new Test.LoginPage())
{
};
}
My Test.LoginPage is a simple empty Xaml page with this C# back end:
public partial class LoginPage : ContentPage
{
public LoginPage()
{
InitializeComponent();
}
protected async override void OnAppearing()
{
await LongRunningTask();
App.MainPage = new AppShell(); // I want to start a shell app
}
}
public partial class AppShell : Shell
{
public AppShell()
{
Routing.RegisterRoute("HomeTab/QHPage", typeof(QHPage));
// etc
But the code has issues in that first of all I am not sure I am doing it correctly and secondly it says an object reference is required for App.MainPage.
Can anyone point me in the right direction and suggest how I could display this intermediate page and then display the real app pages?
Note that at some point I would also like to have a button on the login page that when clicked takes me to the app. But at this time I just want to get even the most simple version working so I am looking for some advice with that.
The easy way is to set the AppShell as MainPage. The code below works for me.
Application.Current.MainPage = new AppShell();

Android Issue with Xamarin forms, mvvmcross, tabs and tasks

So i am using mvvmcross 6.2 and Xamarin Forms. I have setup the tabs using this informaiton Is there tabbed layout platform provided by mvvmcross?. I have an iOS app that works fine, When running the android app i get the following exception whenever initating one of the tasks.
Java.Lang.IllegalStateException: 'FragmentManager is already executing transactions'
The app is not busy while doing this so the busy indicator is not showing , however the app takes a very long time to change from login page to the tabs home. the exception does not seem to stop the process but it does really slow down the loading.
in my homeviemodel
public async Task ShowInitialViewModels()
{
tasks.Add(NavigationService.Navigate<tab1ViewModel>());
tasks.Add(NavigationService.Navigate<tab2ViewModel>());
tasks.Add(NavigationService.Navigate<tab3ViewModel>());
tasks.Add(NavigationService.Navigate<tabViewModel>());
await CheckFortab5ViewModel();
await Task.WhenAll(tasks);
}
in my home xaml
[XamlCompilation(XamlCompilationOptions.Compile)]
[MvxTabbedPagePresentation(TabbedPosition.Root, WrapInNavigationPage = true, Animated = false)]
public partial class HomePage : MvxTabbedPage<HomeViewModel>
{
in my tabs
[XamlCompilation(XamlCompilationOptions.Compile)]
[MvxTabbedPagePresentation(TabbedPosition.Tab, WrapInNavigationPage = false, NoHistory = true)]
public partial class tab1page: MvxContentPage<tab1ViewModel>
{
any ideas? should i even be worried about this?

Override Fragment functions on Xamarin Android if fragment is created using Forms Embedding

I have created a forms page in Xamarin and used that page as a fragment using Xamarin Forms Embedding.
var fragment = new FormsPage().CreateFragment(context);
I would like to override the OnBackPressed() control in Android version of the app.
What's the best possible way to do it as I can't override it inside the Xamarin Forms Page.
I would like to override the OnBackPressed() control in Android version of the app.
You could override OnBackButtonPressed in Xamarin.Forms, this event also be raised when the hardware back button is pressed in Android and this event is not raised on iOS.
If you want remove fragment from the stack in OnBackPressed() method, you could override this method in your Activity like this :
public override void OnBackPressed()
{
base.OnBackPressed();
if (FragmentManager.BackStackEntryCount != 0)
{
FragmentManager.PopBackStack();
}
else
{
base.OnBackPressed();
}
}

How to present an iOS Modal View in MvvmCross

How can I present a modal view on iOS using MvvmCross?
Using Xamarin Studio on iOS and the MvvmCross NuGet version 4.2.2, none of the MvxModalSupportTouchViewPresenter, MvxModalNavSupportTouchViewPresenter or IMvxModalTouchView are even available.
Does the ViewModel even need to know about the fact that a particular view is presented as a modal view on iOS?
MvvmCross is a strong Page navigation framework. Default navigation using ShowViewModel<AViewModel> will use the stack metaphor: one on top of another on Android, slide atop each other on iOS, and use < on either platform to go back.
You can tell the ViewPresenter that a given view is modal by giving it a hint, in the form of an interface marker, by adopting IMvxModalIosView.
At the View Level
Adopt the IMvxModalIosView protocol:
public partial class AView : MvxViewController, IMvxModalIosView
At the AppDelegate Level
Replace var setup = new Setup(this, Window) by:
var presenter = new MvxModalSupportIosViewPresenter(this, Window);
var setup = new Setup(this, presenter);
setup.Initialize();
At the ViewModel Level
No change required. The ViewModel is actually not made aware of the modal presentation. Invoke:
ShowViewModel<AViewModel> // May be modal on certain platforms
To close a Page and go back to the previous one, regardless of your presentation style, use Close(this) on that very ViewModel. This will close a modal dialog, or pop a pushed view. A complete, bindable ICommand may look like this:
public ICommand BackCommand {
get { return new MvxCommand(() => Close(this)); }
}
Notes: In MvvmCross 4.2.2, Touch has been renamed iOS, so IMvxModalTouchView is now IMvxModalIosView. The new using are:
using MvvmCross.iOS.Platform;
using MvvmCross.iOS.Views.Presenters;
Using MvvmCross 5.5.2 all I had to get a modal was to add the following MvxModalPresentation attribute to my iOS view:
[Register("ExampleModalView")]
[MvxModalPresentation(
ModalPresentationStyle = UIModalPresentationStyle.PageSheet,
ModalTransitionStyle = UIModalTransitionStyle.CoverVertical
)]
public class ExampleModalView : MvxViewController
{
public ExampleModalView() {
}
...
}
Launching the modal is simple with the IMvxNavigationService service
await _navigationService.Navigate<ExampleModalViewModel>();
ExampleModalViewModel just needs to be a plain MvvmCross view model inheriting from MvxViewModel.
A useful reference for this is ModalView.cs in the iOS playground project: https://github.com/MvvmCross/MvvmCross/blob/develop/TestProjects/Playground/Playground.iOS/Views/ModalView.cs#L12

MvvmCross vnext: CheckBox CheckedChange event to a command with monodroid

I'm trying to bind CheckedChange from monodroid CheckBox to a command, but I get an error.
I want to unselect another item when a particular one is checked.
I think it is possible to do it with EventTrigger in wp7, but MvvmCross for android doesn't seem to support this feature.
Is MvvmCross limited to Button only ?
Thanks in advance for your help.
CheckedChanged is an EventHandler<CompoundButton.CheckedChangeEventArgs> so it isn't one of the delegate types that MvvmCross automatigically knows about.
However, there is a custom binding in place for this...
https://github.com/slodge/MvvmCross/blob/vnext/Cirrious/Cirrious.MvvmCross.Binding.Droid/Target/MvxCompoundButtonCheckedTargetBinding.cs
And this custom binding should be registered using:
registry.RegisterFactory(new MvxSimplePropertyInfoTargetBindingFactory(typeof(MvxCompoundButtonCheckedTargetBinding), typeof(CompoundButton), "Checked"));
in https://github.com/slodge/MvvmCross/blob/vnext/Cirrious/Cirrious.MvvmCross.Binding.Droid/MvxAndroidBindingBuilder.cs
So if you have a ViewModel with a property IsSpecial
private bool _isSpecial;
public bool IsSpecial
{
get { return _isSpecial; }
set
{
_isSpecial = value;
RaisePropertyChanged(() => IsSpecial);
// your custom code here
}
}
then this binding should work:
'Checked':{'Path':'IsSpecial'}
And that should work for any CompoundButton - CheckBox, Switch, or your own compounds...

Resources