Xamarin.Forms 的 BaseViewModel

最近在研究用C#开发安卓应用,头大呀,这方面的资料真的非常少,毕竟非主流呀。

一开始用了MAUI,谁知道用VS2022创建的初始项目都跑不起来,各种BUG。

无奈呀,最后只能找上它了,没错,就是Xamarin.Forms;

一上手发现,开发模式如此的熟悉,毕竟之前一直玩WPF;

所以就自个琢磨着把WPF那一套VM的基类实现转移了过来,发现一样好用呀;

不多说直接上代码:

首先是BaseModel

 public class BaseModel : System.ComponentModel.INotifyPropertyChanged
 {

     public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
     public void OnPropertyChanged([System.Runtime.CompilerServices.CallerMemberName] string propertyName = "")
     {
         if (PropertyChanged != null)
         {
             PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
         }
     }
 }

接下来就是BaseViewModel啦

 public class BaseViewModel : BaseModel
 {

     //程序的主命名空间
     public string UINameSapce = "";
     //类名
     public string UIElementName = "";
     public VisualElement UIElement { get; set; }

     private System.Type UIType;

     /// <summary>
     /// ViewModel基类  需要传UI界面的全名(FullName)参数
     /// </summary>
     /// <param name="uiType">UI界面的类型</param>
     public BaseViewModel(System.Type uiType)
     {
         try
         {
             UIType = uiType;
             UINameSapce = uiType.Namespace;
             SetUIElement();
             UIElement.BindingContext = this;
             OnLoad();
         }
         catch (System.Exception ex)
         {
             throw ex;
         }
     }

     /// <summary>
     /// ViewModel基类,直接传入UI界面对象
     /// </summary>
     /// <param name="ui"></param>
     public BaseViewModel(VisualElement ui)
     {
         try
         {
             UIType = ui.GetType();
             UINameSapce = UIType.Namespace;
             UIElementName = UIType.FullName;
             UIElement = ui;
             //UIElement.BindingContext = this;
         }
         catch (System.Exception ex)
         {
             throw ex;
         }
     }

     #region 界面加载方法
     /// <summary>
     /// 需要手动调用
     /// </summary>
     public virtual void OnLoad()
     {

     }
     /// <summary>
     /// 需要手动调用
     /// </summary>
     public virtual void UnLoad()
     {

     }


     #endregion

     #region 通过反射创建对应的UI元素

     /// <summary>
     /// 根据VM名称,反射对应类型的UI实例
     /// </summary>
     internal void SetUIElement()
     {
         System.Type childType = this.GetType();//获取子类的类型   
         UIElementName = this.GetType().FullName;
         UIElement = (View)GetElement();
     }

     /// <summary>
     /// 用UI全名称(FullName)进行反射UI实例
     /// </summary>
     /// <typeparam name="E"></typeparam>
     /// <param name="UIElementFullName"></param>
     /// <returns></returns>
     public object GetElement()
     {
         if (UIType != null)
         {
             return System.Activator.CreateInstance(UIType);
         }
         else
         {
             throw new System.Exception("UIType为空");
         }
     }

     #endregion

     #region   异步线程

     /// <summary>
     /// 异步方法执行事件
     /// </summary>
     public void AsyncLoad(System.Action action)
     {
         System.IAsyncResult result = action.BeginInvoke((iar) =>
         {
         }, null);
     }

     /// <summary>
     /// 异步方法执行事件 带回调方法
     /// </summary>
     public void AsyncLoad(System.Action action, System.Action callback)
     {
         System.IAsyncResult result = action.BeginInvoke((iar) =>
         {
             this.DoMenthodByDispatcher(callback);
         }, null);
     }

     /// <summary>
     /// 异步方法执行事件 带参数及带回调方法
     /// </summary>
     public void AsyncLoad<T>(System.Action<T> action, T para, System.Action callback)
     {
         System.IAsyncResult result = action.BeginInvoke(para, (iar) =>
         {
             this.DoMenthodByDispatcher(callback);
         }, null);
     }

     /// <summary>
     /// 异步方法执行事件 带参数及带回调方法
     /// </summary>
     public void AsyncLoad<T, R>(System.Func<T, R> action, T para, System.Action<R> callback)
     {
         System.IAsyncResult result = action.BeginInvoke(para, (iar) =>
         {
             var res = action.EndInvoke(iar);
             this.DoMenthodByDispatcher<R>(callback, res);
         }, null);
     }

     /// <summary>
     /// 异步方法执行事件 带回调方法
     /// </summary>
     /// <typeparam name="R"></typeparam>
     /// <param name="action"></param>
     /// <param name="callback"></param>
     public void AsyncLoad<R>(System.Func<R> action, System.Action<R> callback)
     {
         System.IAsyncResult result = action.BeginInvoke((iar) =>
         {
             var res = action.EndInvoke(iar);
             this.DoMenthodByDispatcher<R>(callback, res);
         }, null);
     }

     /// <summary>
     /// 使用UI线程执行Action 带参数  默认 异步(BeginInvoke)执行
     /// </summary>
     /// <typeparam name="T">泛型参数</typeparam>
     /// <param name="action">执行的方法</param>
     /// <param name="obj">参数</param>
     public void DoMenthodByDispatcher<T>(System.Action<T> action, T obj)
     {
         UIElement?.Dispatcher.BeginInvokeOnMainThread(new System.Action(() =>
         {
             action(obj);
         }));

     }

     /// <summary>
     ///使用UI线程执行Action  默认 异步(BeginInvoke)执行
     /// </summary>
     /// <param name="action"></param>
     public void DoMenthodByDispatcher(System.Action action)
     {
         UIElement?.Dispatcher.BeginInvokeOnMainThread(new System.Action(() =>
         {
             action();
         }));
     }
     #endregion  
 }

因Xamarin.Forms中没有 Load和UnLoad的事件绑定,所以我在基类添加了两个方法 Load和UnLoad;

Load方法在BaseViewModel构造函数中调用了;

然后UnLoad的话,界面用的Frame控件切换界面,通过属性绑定,在切换时调用UnLoad的方法;

  <Frame
      x:Name="MainFrame"
      Grid.Row="1"
      Margin="0"
      BackgroundColor="Transparent"
      Content="{Binding ViewUri}"
      CornerRadius="0"
      HorizontalOptions="FillAndExpand"
      VerticalOptions="FillAndExpand" />
 private View _viewUri;
 /// <summary>
 /// 界面Frame对象
 /// </summary>
 public View ViewUri
 {
     get { return _viewUri; }
     set
     {
         try
         {
             if (_viewUri != null)
             {
                 ((BaseViewModel)_viewUri.BindingContext).UnLoad();
             }
         }
         catch { }
         _viewUri = value;
         OnPropertyChanged();
     }
 }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Rotion_深

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值