MVVM_Xamarin StartApp工程

来源:互联网 发布:电脑为什么找不到网络 编辑:程序博客网 时间:2024/05/17 02:54

MVVM_Xamarin StartApp工程

github地址:https://github.com/yaocunli/MvvMFirstApp


1. 创建工程

这里写图片描述

2. 添加必要的包(MvvmCross)

这里只在core工程和iOS工程下导入包,Android工程暂时不写(开始写工程之前,先编译运行运行一下程序,没有问题再写代码!)
这里写图片描述

3. 开始Core 工程,首先Service

1). 接口ICalculation用来抽象计算小费的逻辑。2). Calculation来实现接口的方法
using System;namespace firstApp.Services{    public interface ICalculation    {        double TipAmount(double subTotal, int generosity);    }}
using System;using firstApp.Services;namespace firstApp.Services{    public class Calculation : ICalculation    {        public double TipAmount(double subTotal, int generosity)        {            return subTotal * ((double)generosity) / 100.0;        }    }}

4. ViewModel

using firstApp.Services;using MvvmCross.Core.ViewModels;namespace firstApp.ViewModel{    public class TipViewModel : MvxViewModel    {        /// <summary>        /// ViewModel:继承与MvxViewModel        /// 这个ViewModel中有3个被扩展过的属性SubTotal、Generosity、Tip。        /// 当他们被修改的时候会调用RaisePropertyChanged函数来通知其他的对象他们的属性被修改过了。        /// 且当SubTotal和Generosity被修改时会重新计算小费。        /// </summary>        private readonly ICalculation _calculation;        private double _subTotal;        private int _generosity;        private double _tip;        public TipViewModel(ICalculation calculation)        {            _calculation = calculation;        }        /// <summary>        /// 重写Start方法,赋初始值;        /// </summary>        public override void Start()        {            _subTotal = 100;            _generosity = 10;            Recalculate();            base.Start();        }        public double SubTotal        {            get { return _subTotal; }            set            {                _subTotal = value;                RaisePropertyChanged(() => SubTotal);                Recalculate();            }        }        public int Generosity        {            get { return _generosity; }            set            {                _generosity = value;                RaisePropertyChanged(() => Generosity);                Recalculate();            }        }        public double Tip        {            get { return _tip; }            private set            {                _tip = value;                RaisePropertyChanged(() => Tip);            }        }        private void Recalculate()        {            Tip = _calculation.TipAmount(SubTotal, Generosity);        }    }}

注意:⚠️命名空间写完整,不然会出现问题!

这里写图片描述

5. 添加app文件

* 他通常会待在在PCL项目的根目录下。* 他继承自MvxApplication。* 一般来说他的名字就叫App。* 他的主要功能是:    * 为IoC容器注册接口以及相应的实现。    * 设置App启动后第一个界面对应的的ViewModel。    * 为整个App提供ViewModel的定位器(Locator)。        * 定位器作用是通过ViewModel的Type以及以下参数来生成对应的ViewModel。通常情况下我们用默认的就行了。
using System;using firstApp.Services;using firstApp.ViewModel;using MvvmCross.Core.ViewModels;using MvvmCross.Platform;namespace firstApp{    public class App : MvxApplication    {        public App()        {            /// <summary>            /// 通常起名:App,继承与MvxApplication类            /// 接口和实现的登记。            /// </summary>            Mvx.RegisterType<ICalculation, Calculation>();            /// <summary>            /// 程序一开始启动的View            /// </summary>            Mvx.RegisterSingleton<IMvxAppStart>(new MvxAppStart<TipViewModel>());        }    }}

或者下面这种写法:

using Cirrious.CrossCore.IoC;using shize.Core.ViewModels;namespace shize.Core{    public class App : Cirrious.MvvmCross.ViewModels.MvxApplication    {        public override void Initialize ()        {            CreatableTypes ()                .EndingWith ("Service")                .AsInterfaces ()                .RegisterAsLazySingleton ();            RegisterAppStart<TipViewModel> ();        }    }}

6. 开始iOS 工程

7. StoryboardViewsContainer

using System;using MvvmCross.iOS.Views;using MvvmCross.Platform.Exceptions;using UIKit;namespace firstApp.iOS.Views{    ///使用Storyboard    public class StoryboardViewsContainer : MvxIosViewsContainer    {        const string ViewModelSuffix = "ViewModel";        const string ControllerSuffix = "View";        UIStoryboard _storyboard;        public StoryboardViewsContainer(string storyboardName)        {            _storyboard = UIStoryboard.FromName(storyboardName, null);        }        public override IMvxIosView CreateView(MvvmCross.Core.ViewModels.MvxViewModelRequest request)        {            var view = CreateViewFromViewModelType(request.ViewModelType);            if (view == null)            {                var viewType = GetViewType(request.ViewModelType);                if (viewType == null)                    throw new MvxException("View Type not found for " + request.ViewModelType);                view = CreateViewOfType(viewType, request);            }            view.Request = request;            return view;        }        protected override IMvxIosView CreateViewOfType(Type viewType, MvvmCross.Core.ViewModels.MvxViewModelRequest request)        {            return CreateView(viewType.Name);        }        IMvxIosView CreateViewFromViewModelType(Type viewModelType)        {            var name = viewModelType.Name;            if (name.EndsWith(ViewModelSuffix))            {                name = name.Substring(0, name.Length - ViewModelSuffix.Length) + ControllerSuffix;            }            return CreateView(name);        }        IMvxIosView CreateView(string viewName)        {            return (IMvxIosView)_storyboard.InstantiateViewController(viewName);        }    }}

8. 添加setup文件,修改app delegate方法

using System;using firstApp.iOS.Views;using MvvmCross.Core.ViewModels;using MvvmCross.iOS.Platform;using MvvmCross.iOS.Views.Presenters;namespace firstApp.iOS{    public class Setup : MvxIosSetup    {        public Setup(MvxApplicationDelegate appDelegate, IMvxIosViewPresenter presenter)            : base(appDelegate, presenter)        {        }        protected override IMvxApplication CreateApp()        {            return new App();        }        protected override MvvmCross.iOS.Views.IMvxIosViewsContainer CreateIosViewsContainer()        {            return new StoryboardViewsContainer("Main");        }    }}
using Foundation;using UIKit;using MvvmCross.iOS.Platform;using MvvmCross.iOS.Views.Presenters;using MvvmCross.Platform;using MvvmCross.Core.ViewModels;namespace firstApp.iOS{    // The UIApplicationDelegate for the application. This class is responsible for launching the    // User Interface of the application, as well as listening (and optionally responding) to application events from iOS.    [Register("AppDelegate")]    public class AppDelegate : MvxApplicationDelegate    {        // class-level declarations        public override UIWindow Window        {            get;            set;        }        public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)        {            var presenter = new MvxIosViewPresenter(this, Window);            var setup = new Setup(this, presenter);            setup.Initialize();            var startup = Mvx.Resolve<IMvxAppStart>();            startup.Start();            Window.MakeKeyAndVisible();            return true;        }

9. 创建View

这里没有使用创建时自带的xib布局,而是在XCode中的storyBoard布局,关联到这个控制器,其中的控件拉到viewcontroller中,xcode保存,会在xamarin中生成对应的outlet属性。

using System;using UIKit;using firstApp.ViewModel;using MvvmCross.iOS.Views;using System.Drawing;using MvvmCross.Binding.BindingContext;namespace firstApp.iOS.Views{    public partial class TipView : MvxViewController    {        public TipView(IntPtr handle) : base(handle)        {        }        //public TipView(string viewName) : base(viewName, null)        //{        //  // this is a constructor        //}        public TipViewModel TipViewModel        {            get            {                return ViewModel as TipViewModel;            }        }        public override void ViewDidLoad()        {            base.ViewDidLoad();            setNavigationItem();            addGesture();            this.CreateBinding(titleLabel).To((TipViewModel vm) => vm.Tip).Apply();            this.CreateBinding(textFieldOne).To((TipViewModel vm) => vm.SubTotal).Apply();            this.CreateBinding(generisitySliderBar).To((TipViewModel vm) => vm.Generosity).Apply();        }        /// <summary>        /// NavigatonItem--setting        /// </summary>        public void setNavigationItem()        {            var image = UIImage.FromBundle("btn_menu_schedule.png");            var backButton = UIButton.FromType(UIButtonType.Custom);            backButton.SetBackgroundImage(image, UIControlState.Normal);            backButton.Frame = new RectangleF(0, 0, 40, 40);            backButton.TouchUpInside += (sender, args) =>            {                Console.WriteLine("11111");            };            NavigationItem.LeftBarButtonItem = new UIBarButtonItem(backButton);        }        public void addGesture()        {            this.View.AddGestureRecognizer(new UITapGestureRecognizer(() =>            {                View.ResignFirstResponder();            }));        }    }}

总结:
1. mvvmcross应用的一般结构:
2. 一个共享的“核心”便携式类库(PCL)项目
3. 包含尽可能多的代码:模型、视图模型、服务、转换器等
4. 每个平台一个UI项目
5. 每个包含该平台的引导和视图特定代码

继承关系
1. ViewModel都需要继承自MvxViewModel
2. App:MvxApplication
3. TipView : MvxViewController
4. Setup : MvxIosSetup
5. AppDelegate : MvxApplicationDelegate

0 0
原创粉丝点击