zoukankan      html  css  js  c++  java
  • 走进 Prism for Xamarin.Forms

    一、使用环境

    OS:Win 10 16273

    VS:VS2017- 15.3.4

    Xamarin:4.6.3.4,nuget:2.4

    Android Emulator:Visual Studio for Android Emulator(相比 Android Emulator不用下载SDK,而且启动快)

    二、安装 Prism 模块

    工具——扩展和更新——搜索 Prism Template Pack——安装

    三、开始搞起

    1.先建个项目

    2.添加页面

    Views文件夹右键——添加——新建项,弹出来的对话框先选中左边的 Prism 节点

    确定后,你会发现 App.xaml.cs 文件里注入了新建的页面, ViewModels 文件夹下也多出了 ViewModel ,Views 新添加的文件也是和 ViewModel 绑定好的

    <?xml version="1.0" encoding="utf-8" ?>
    <ContentPage
        x:Class="SD.Xamarin.Views.LoginPage"
        xmlns="http://xamarin.com/schemas/2014/forms"
        xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
        xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
        Title="Login"
        prism:ViewModelLocator.AutowireViewModel="True">
    
        <ContentPage.ToolbarItems>
            <ToolbarItem Text="Regist" />
        </ContentPage.ToolbarItems>
    
        <StackLayout
            Padding="20"
            Spacing="20"
            VerticalOptions="Center">
    
            <Entry Placeholder="Username" Text="{Binding Username}" />
            <Entry
                IsPassword="true"
                Placeholder="Password"
                Text="{Binding Password}" />
    
            <Button
                BackgroundColor="#77D065"
                Command="{Binding LoginCommand}"
                Text="Login"
                TextColor="White" />
        </StackLayout>
    
    </ContentPage>
    
    public class LoginPageViewModel : BindableBase
        {
            private readonly INavigationService _navigationService;
            private readonly IEventAggregator _eventAggregator;
            private readonly IPageDialogService _pageDialogService;
    
    
            private string _username;
    
            public string Username
            {
                get { return _username; }
                set
                {
                    _username = value;
                    RaisePropertyChanged();
                }
            }
    
            private string _password;
    
            public string Password
            {
                get { return _password; }
                set
                {
                    _password = value;
                    RaisePropertyChanged();
                }
            }
    
            private ICommand _loginCommand;
    
            public ICommand LoginCommand
            {
                get { return _loginCommand ?? new DelegateCommand(Login); }
                set { _loginCommand = value; }
            }
    
            public LoginPageViewModel(INavigationService navigationService, IEventAggregator eventAggregator, IPageDialogService pageDialogService)
            {
                _navigationService = navigationService;
                _eventAggregator = eventAggregator;
                _pageDialogService = pageDialogService;
            }
    
            private async void Login()
            {
                if (!string.IsNullOrEmpty(Username) && !string.IsNullOrEmpty(Password))
                {
                    await _navigationService.NavigateAsync(nameof(DataCabinPage));
                }
                else
                {
                    await _pageDialogService.DisplayAlertAsync("Error", "Wrong Username or Password", "OK!");
                }
            }
        }
    

    3.添加一个 Master 页面作为主页面

    <?xml version="1.0" encoding="utf-8" ?>
    <MasterDetailPage
        x:Class="SD.Xamarin.Views.MasterPage"
        xmlns="http://xamarin.com/schemas/2014/forms"
        xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
        xmlns:behaviors="clr-namespace:Prism.Behaviors;assembly=Prism.Forms"
        xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
        xmlns:views="clr-namespace:SD.Xamarin.Views;assembly=SD.Xamarin"
        Title="Master"
        prism:ViewModelLocator.AutowireViewModel="True">
    
        <MasterDetailPage.Master>
            <NavigationPage Title="Required Foo" Icon="hamburger.png">
                <x:Arguments>
                    <views:DataCabinPage />
                </x:Arguments>
            </NavigationPage>
        </MasterDetailPage.Master>
    
    </MasterDetailPage>
    

     Master里的子页面

    <?xml version="1.0" encoding="utf-8" ?>
    <ContentPage
        x:Class="SD.Xamarin.Views.DataCabinPage"
        xmlns="http://xamarin.com/schemas/2014/forms"
        xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
        xmlns:behaviors="clr-namespace:Prism.Behaviors;assembly=Prism.Forms"
        xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
        Title="DataCabin"
        prism:ViewModelLocator.AutowireViewModel="True">
    
        <ContentPage.ToolbarItems>
            <ToolbarItem Command="GoBackCommand" Text="Back" />
        </ContentPage.ToolbarItems>
    
        <ListView
            x:Name="listView"
            CachingStrategy="RecycleElement"
            GroupDisplayBinding="{Binding Key}"
            GroupShortNameBinding="{Binding Key}"
            IsGroupingEnabled="True"
            ItemsSource="{Binding DataCabinsGrouped}"
            SelectedItem="{Binding SelectedDataCabin}">
    
            <ListView.Behaviors>
                <behaviors:EventToCommandBehavior Command="{Binding ItemTappedCommand}" EventName="ItemTapped" />
            </ListView.Behaviors>
    
    <ListView.GroupHeaderTemplate> <DataTemplate> <ViewCell> <StackLayout Orientation="Horizontal"> <Image Source="hamburger.png" /> <Label FontSize="18" Text="{Binding Key}" TextColor="DeepSkyBlue" VerticalTextAlignment="Center" /> </StackLayout> </ViewCell> </DataTemplate> </ListView.GroupHeaderTemplate> <ListView.ItemTemplate> <DataTemplate> <ViewCell> <Label Text="{Binding Name}" TextColor="White" VerticalTextAlignment="Center" /> </ViewCell> </DataTemplate> </ListView.ItemTemplate> </ListView> </ContentPage>
    public class DataCabinPageViewModel : BindableBase
        {
            private readonly INavigationService _navigationService;
            private readonly IEventAggregator _eventAggregator;
            private readonly IPageDialogService _pageDialogService;
    
            private DataCabinModel _selectedDataCabin;
    
            public DataCabinModel SelectedDataCabin
            {
                get { return _selectedDataCabin; }
                set
                {
                    _selectedDataCabin = value;
                    RaisePropertyChanged();
                }
            }
    
            private ObservableCollection<DataCabinModel> _dataCabins;
    
            public ObservableCollection<DataCabinModel> DataCabins
            {
                get { return _dataCabins; }
                set
                {
                    _dataCabins = value;
                    RaisePropertyChanged();
                }
            }
    
            private ObservableCollection<GroupingModel<string, DataCabinModel>> _dataCabinsGrouped;
    
            public ObservableCollection<GroupingModel<string, DataCabinModel>> DataCabinsGrouped
            {
                get { return _dataCabinsGrouped; }
                set
                {
                    _dataCabinsGrouped = value;
                    RaisePropertyChanged();
                }
            }
    
            private ICommand _itemTappedCommand;
    
            public ICommand ItemTappedCommand
            {
                get { return _itemTappedCommand ?? new DelegateCommand(ItemTapped); }
                set { _itemTappedCommand = value; }
            }
    
            private ICommand _goBackCommand;
    
            public ICommand GoBackCommand
            {
                get { return _goBackCommand ?? new DelegateCommand(GoBack); }
                set { _goBackCommand = value; }
            }
    
            public DataCabinPageViewModel(INavigationService navigationService, IEventAggregator eventAggregator, IPageDialogService pageDialogService)
            {
                _navigationService = navigationService;
                _eventAggregator = eventAggregator;
                _pageDialogService = pageDialogService;
    
                DataCabins = new ObservableCollection<DataCabinModel>()
                {
                    new DataCabinModel(){Id=1,Name = "T1",GroupName="G1",DisplayType= DataCabinType.Chart},
                    new DataCabinModel(){Id=2,Name = "T2",GroupName="G1",DisplayType= DataCabinType.Grid},
                    new DataCabinModel(){Id=3,Name = "T3",GroupName="G2",DisplayType= DataCabinType.Guage},
                    new DataCabinModel(){Id=4,Name = "T4",GroupName="G2",DisplayType= DataCabinType.Map}
                };
    
                var grouped = from menuItem in DataCabins
                              orderby menuItem.Id
                              group menuItem by menuItem.GroupName into menuItemGroup
                              select new GroupingModel<string, DataCabinModel>(menuItemGroup.Key, menuItemGroup);
    
                DataCabinsGrouped = new ObservableCollection<GroupingModel<string, DataCabinModel>>(grouped);
            }
    
            private async void ItemTapped()
            {
                switch (SelectedDataCabin.DisplayType)
                {
                    case DataCabinType.Chart:
                        await _navigationService.NavigateAsync("/Master/Navigation/" + nameof(ChartPage));
                        break;
                    case DataCabinType.Grid:
                        await _navigationService.NavigateAsync("/Master/Navigation/" + nameof(GridPage));
                        break;
                    case DataCabinType.Guage:
                        await _navigationService.NavigateAsync("/Master/Navigation/" + nameof(GuagePage));
                        break;
                    case DataCabinType.Map:
                        await _navigationService.NavigateAsync("/Master/Navigation/" + nameof(MapPage));
                        break;
                    default:
                        throw new ArgumentOutOfRangeException();
                }
    
            }
    
            private void GoBack()
            {
                _navigationService.NavigateAsync(nameof(DataCabinPage));
            }
        }
    

    App.xaml

    public partial class App : PrismApplication
        {
            public App(IPlatformInitializer initializer = null) 
                : base(initializer)
            { }
    
            protected override void OnInitialized()
            {
                InitializeComponent();
    
                NavigationService.NavigateAsync(nameof(LoginPage));
            }
    
            protected override void RegisterTypes()
            {
                Container.RegisterTypeForNavigation<NavigationPage>("Navigation");
    
                Container.RegisterTypeForNavigation<RegistPage>();
                Container.RegisterTypeForNavigation<LoginPage>();
                Container.RegisterTypeForNavigation<MasterPage>("Master");
                Container.RegisterTypeForNavigation<ChartPage>();
                Container.RegisterTypeForNavigation<GridPage>();
                Container.RegisterTypeForNavigation<GuagePage>();
                Container.RegisterTypeForNavigation<MapPage>();
                Container.RegisterTypeForNavigation<DataCabinPage>();
            }
        }
    

    这是最终的 App 文件,注意其中的NavigationPage 和MasterPage 后边都加了参数,用来导航用的,因为想要汉堡包样式 

    汉堡包的图片是从官方例子复制的,需要放到

    Android:

    IOS:直接 Resources 文件夹下

    导航的写法  await _navigationService.NavigateAsync("/Master/Navigation/" + nameof(ChartPage));  这里就是App.xaml.cs 文件里注册时的那个参数,本来想把前边也写出nameof 的方式,但是发现直接失败了,就只能这样了

    其他的代码都很建单,也没写什么逻辑,就不贴了,大概就是这个样子,嗯,下一步就要引入 syncfusion 的控件才行了,这样才好看,也能有很多控件用(主要是实在不知道写什么业务)

    动态图

    四、模拟器

    工具——Visual Studio Emulator for Android 弹出的里边选择一个下载就好了,是基于Hyper-V 的,需要确定你的机器支持

    窗口——其他窗口——Xamarin.Forms Previewer 也是可以预览的,但是用了Prism 后,App.xaml.cs 里的构造函数变了,然后就显示不了了~~

     

    五、遇到的问题

    1.F5 运行后,执行了 编译——部署,然后就停了,不能像WPF 项目一样实时Debug ,也不知道需要配置什么,这样一旦出错,就得一点点试,很不舒服

    2.点击主页后跳转到子页面,再弹出汉堡包跳转第二个,再跳转第三个后 程序就崩溃了,也不知道为什么 

    3.有时页面的ToolbarItem 不显示,但是放到汉堡包里的那个就显示,不知道怎么搞的,

    以上问题有知道的,请多指教啊

    六、总结

    Xamarin 整合到VS 里后,环境配置相比刚出来时好配置好多,VS Emulator 的加入也省去了下载 Android SDK时的困难,而且还特别大,虽然VS的某些功能还是需要FQ下载。

    WP已死,没必要开发,UWP 肯定是回到桌面的 UWP 开发比较好,调试和用法更好用,而且还可以查看虚拟树什么的,好方便的。

    CM框架也要出4.0了,到时再试试CM

    七、参考例子

    Prism:https://github.com/PrismLibrary/Prism-Samples-Forms

    Xamarin:https://github.com/xamarin/xamarin-forms-samples

  • 相关阅读:
    IntelliJ IDEA Community Edition 14.1.4下使用 Apache-Subversion搭建代码管理环境
    Eclipse+SVN搭建开发环境
    查看分区表中分区详细信息
    asp.net mvc 后台怎么接受前端返回的array list dictionary
    jquery 操作select
    asp.net mvc4 System.Web.Optimization找不到引用
    asp.net mvc4 设置build项目时,编译view页面
    c# ConfigurationSection
    Array基本操作
    For,Function,Lazy
  • 原文地址:https://www.cnblogs.com/heyixiaoran/p/7519942.html
Copyright © 2011-2022 走看看