上下文:我收到了这个不使用ViewModels或任何MVVM框架的大型企业iOS和Android Xamarin Native应用程序。它确实具有单独的网络服务层,并且具有很多页面,因此从头开始没有任何意义。

为什么需要更改:没有MVVM,直接从UI类(Fragments和ViewControllers)调用服务层,并且没有很好的抽象。因此,我将从1个 View 开始,然后创建TechDebt来转换应用程序的其余部分。

我所知道的:

  • 添加MVVM框架需要进行大量更改,尤其是要使用导航服务来浏览 View 时,最好在绿色应用程序添加时进行。
  • here所示,Android有一种使用ViewModel的简便方法,但那时我将无法在iOS中使用它。
  • 我也知道我可以改为启动Xamarin Forms页面,这将为MVVM做好一切准备,因为我可以将BindingContext属性分配给ViewModel的实例。

  • 我需要什么:我需要为iOS创建一个新页面,为Android创建一个新页面。我希望能够创建在iOS和Android之间共享的ViewModel。我希望能够将其用于正在创建的单个 View ,并且应该在加载页面时对其进行初始化。

    如何添加由ViewController和Fragment共享的1个ViewModel?我是否缺少某些东西,这比我做的容易吗?

    最佳答案

    最终可以为此使用MvvmLight。在项目中添加了Nuget包,在核心共享库项目中创建了ViewModelBase:

    public abstract class ViewModelBase : GalaSoft.MvvmLight.ViewModelBase
    {
            private PropertyChangedEventHandler propertyChangedEventHandler;
    
            protected bool IsLoading { get; set; }
    
            public bool RegisteredPropertyEventHandler { get; set; }
    
            public const string ErrorMessagePropertyName = "ErrorMessage";
    
            public string ErrorMessage { get; set; }
    
            public string SuccessMessage { get; set; }
    
            public void RegisterPropertyEventHandler(PropertyChangedEventHandler propertyChangedEventHandler)
            {
                this.propertyChangedEventHandler = propertyChangedEventHandler;
                this.PropertyChanged += propertyChangedEventHandler;
                this.RegisteredPropertyEventHandler = true;
            }
    
            public void UnegisterPropertyEventHandler()
            {
                if (this.RegisteredPropertyEventHandler)
                {
                    this.PropertyChanged -= propertyChangedEventHandler;
                    this.RegisteredPropertyEventHandler = false;
                    this.propertyChangedEventHandler = null;
                }
            }
    
            public void TearDown()
            {
                this.UnegisterPropertyEventHandler();
            }
    
            protected void NotifyError (string message)
            {
                this.ErrorMessage = message;
                RaisePropertyChanged (() => ErrorMessage);
            }
    }
    

    和一个ViewModelLocator
    public class ViewModelLocator
    {
            public const string ABCPageKey = "ABCPage";
    
            public ABCViewModel ABC
            {
                get
                {
                    return ServiceLocator.Current.GetInstance<ABCViewModel> ();
                }
            }
    
            public ViewModelLocator ()
            {
                ServiceLocator.SetLocatorProvider (() => SimpleIoc.Default);
    
                // Register all of the view models
                SimpleIoc.Default.Register<ABCViewModel> ();
            }
    
            public static void Cleanup ()
            {
            }
    
            public T GetViewModel<T> ()
            {
                return ServiceLocator.Current.GetInstance<T> ();
            }
    }
    

    在iOS方面,我已经有一个BaseUIViewController,因此我在其之上创建了BaseViewModelUIViewController
    public abstract partial class BaseViewModelUIViewController<T> : BaseUIViewController where T : ViewModelBase
        {
            public T ViewModel
            {
                get
                {
                    return App.Locator.GetViewModel<T> ();
                }
            }
    
            public BaseViewModelUIViewController (IntPtr handle) : base (handle)
            {
            }
    
            internal virtual void ViewModelPropertyChangedHandler (object sender, PropertyChangedEventArgs e)
            {
                Console.WriteLine (string.Format ("****** Property Changed for {0} in {1}", e.PropertyName, this.GetType ().Name));
                switch (e.PropertyName)
                {
                default:
                    break;
                }
            }
    }
    

    然后是Android,同样,我已经有一个BaseFragment,所以我在它之上创建了BaseViewModelFragment
    public class BaseViewModelFragment<T> : BaseFragment where T : ViewModelBase
    {
            public T ViewModel
            {
                get
                {
                    return App.Locator.GetViewModel<T> ();
                }
            }
    
            public BaseViewModelFragment (string title) : base (title)
            {
            }
    
            internal virtual void ViewModelPropertyChangedHandler (object sender, PropertyChangedEventArgs e)
            {
                Console.WriteLine (string.Format ("****** Property Changed for {0} in {1}", e.PropertyName, this.GetType ().Name));
                switch (e.PropertyName)
                {
                default:
                    break;
                }
            }
    
            public override void OnDestroyView ()
            {
                this.ViewModel.TearDown ();
    
                base.OnDestroyView ();
            }
    }
    

    我希望这对寻求解决方案的其他人有意义。

    创建ViewModel:自然地,对于创建的每个新ViewModel,我都必须在ViewModelLocator中注册它。

    使用ViewModels:就用法而言,您可以在UI中使用ViewModel,只需继承iOS的“:BaseViewModelUIViewController”或Android的“:BaseViewModelFragment”

    关于xamarin - 如何为Xamarin native iOS和Android应用程序的新页面添加ViewModel,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56675748/

    10-11 22:40
    查看更多