上下文:我收到了这个不使用ViewModels或任何MVVM框架的大型企业iOS和Android Xamarin Native应用程序。它确实具有单独的网络服务层,并且具有很多页面,因此从头开始没有任何意义。
为什么需要更改:没有MVVM,直接从UI类(Fragments和ViewControllers)调用服务层,并且没有很好的抽象。因此,我将从1个 View 开始,然后创建TechDebt来转换应用程序的其余部分。
我所知道的:
我需要什么:我需要为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/