caz162
caz162

Reputation: 35

Data binding for Native Views in Maui

We have been tasked with migrating a Xamarin.iOS app to Maui. The app heavily uses MvvmCross to deal with the binding of Views and ViewModels. Essentially these are UIViews that are binding to ViewModels.

I know Maui allows for us to render the UIView with a custom handler. I have had to embed this UIView in a content page but doing this displays the UIView correctly. However we cannot seem to get bindings to work correctly. Essentially I would like to bind this UIView to the ViewModel. Things like binding a button to a Command on the ViewModel, or a UITextField to the ViewModel.

What I can't find in Maui is a way to bind this native view to a ViewModel.

We are happy to ditch MvvmCross but cannot find a suitable replacement.

Here is an stripped down example of our native view.

ChangePasswordView.cs

public class ChangePasswordView : MvxViewController
    {
        private GenericChangePasswordView _genericChangePasswordView;

        public UITextField _oldPasswordTextField;        

        public ChangePasswordView(GenericChangePasswordView genericChangePasswordView)
        {            
            _genericChangePasswordView = genericChangePasswordView;
            
            _oldPasswordTextField = new UITextField(new CGRect(120, 120, 300, 40))
            {
                LeftView = new UIView(new CGRect(0, 0, 10, 10)),
                LeftViewMode = UITextFieldViewMode.Always,
                BackgroundColor = UIColor.White,
                VerticalAlignment = UIControlContentVerticalAlignment.Center,
                ShouldReturn = _ =>
                {
                    return false;
                },
                Placeholder = "Old password",
                SecureTextEntry = true,
            };
            Add(_oldPasswordTextField);

            var vm = _genericChangePasswordView.BindingContext as ChangePasswordViewModel;
            this.DelayBind(() =>
            {
                var set = this.CreateBindingSet<ChangePasswordView, ChangePasswordViewModel>();
                set.Bind(_oldPasswordTextField).To(m => m.OldPassword);
                set.Apply();
            });
        }        
    }

and our ViewModel ChangePasswordViewModel.cs

    public class ChangePasswordViewModel : MvxViewModel
    {
        private decimal _oldPassword;
        public decimal OldPassword
        {
            get => _oldPassword;
            set { _oldPassword = value; RaisePropertyChanged(nameof(OldPassword)); }
        }        
    }

I have attempted to create handlers The cross platform ChangePasswordViewHandler.cs

    public partial class ChangePasswordViewHandler
    {
        public static IPropertyMapper<GenericChangePasswordView, ChangePasswordViewHandler> PropertyMapper = new PropertyMapper<GenericChangePasswordView, ChangePasswordViewHandler>(ViewHandler.ViewMapper)
        {
        };

        public static CommandMapper<GenericChangePasswordView, ChangePasswordViewHandler> CommandMapper = new(ViewCommandMapper)
        {
        };

        public ChangePasswordViewHandler() : base(PropertyMapper, CommandMapper)
        {
        }
    }

The Native Handler ChangePasswordViewHandler.iOS.cs

public partial class ChangePasswordViewHandler : ViewHandler<GenericChangePasswordView, ChangePasswordView>
    {
        protected override ChangePasswordView CreatePlatformView() => new ChangePasswordView(VirtualView);

        protected override void ConnectHandler(ChangePasswordView platformView)
        {
            base.ConnectHandler(platformView);
        }

        protected override void DisconnectHandler(ChangePasswordView platformView)
        {
            platformView.Dispose();
            base.DisconnectHandler(platformView);
        }
    }

What I need to understand is if this is possible to bind this native view to its view model in Maui?

Upvotes: 1

Views: 443

Answers (1)

Liyun Zhang - MSFT
Liyun Zhang - MSFT

Reputation: 14469

First of all, if your old project is Xamarin.iOS not Xamarin Forms. I suggest you migrate the Xamarin.iOS project to .Net iOS. You can refer to the official document about Xamarin Apple project migration.

The .net maui is used the cross-platform controls in the xaml instead of the platform native control. And the xaml doesn't support to use the native view in it directly.

And if you still want to migrate it to maui. You can implement the custom cross-platform control istead of the custom native control.

Upvotes: 1

Related Questions