Search code examples
xamarin.androidmvvmcrossandroid-dialogfragment

Android access MvxDialogFragment view from service


I am using MVVMCross, and have a problem with MvxDialogFragment bindings. I have a base service, which is resolved in Core PCL project, add custom services implementations in iOS and Android projects derived from the base service class.

In android service i construct and show MvxDialogFragment instance:

var top = (MvxFragmentActivity)Mvx.Resolve<IMvxAndroidCurrentTopActivity>().Activity;

if (top == null)
{
    throw new MvxException("Cannot get current top activity");
}

var dlg = new AlertDialog.Builder(top);
dlg.Create().Show();

dialog = new MyDialog
{
    Cancelable = false
};
dialog.Show(top.SupportFragmentManager, "");

And i have simple dialog layout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/test_click_button"
        android:text="Test"
        app:MvxBind="Click TestClickCommand" />
</LinearLayout>

So my goal is to acces base service commands from dialogFragment, which is instantiated from service. How can i do that?

As an alternative, i want to handle my button click in service, but cannot find a way to do this, because my View, ViewModel or Dialog properties are null.

How it's possible to handle clicks in service, or implement self binding?


Solution

  • Finally i achieved the desired, through MvxDialogFragment subscription, and service injection:

    public class MyDialog : MvxDialogFragment
    {
        private ISampleService _sampleService;
    
        public MyDialog(ISampleService sampleService)
        {
            _sampleService = sampleService;
        }
    
        public override Dialog OnCreateDialog(Bundle savedInstanceState)
        {
            EnsureBindingContextSet(savedInstanceState);
    
            var dialog = new AlertDialog.Builder(Activity);
            var view = this.BindingInflate(Resource.Layout.MyDialog, null);
    
            view.FindViewById(Resource.Id.test_click_button).Click += (sender, e) =>
            {
                _sampleService.TestClick();
                Dismiss();
            };
    
            dialog.SetView(view);
    
            return dialog.Create();
        }
    }