一、使用环境

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的某些功能还是需要翻墙下载。

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

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

七、参考例子

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

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

Prism for Xamarin.Forms的更多相关文章

  1. 走进 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 fo ...

  2. LINKs: Xamarin.Forms + Prism

    LINK 1 - How to use Prism with Xamarin.Forms http://brianlagunas.com/first-look-at-the-prism-for-xam ...

  3. 走进 UITest for Xamarin.Forms

    上一篇  走进 Prism for Xamarin.Forms 讲了简单的创建一个项目,然后添加了几个页面来回切换,这篇想先搞下 UITest 官方详细地址:https://developer.xam ...

  4. 老司机学新平台 - Xamarin Forms开发框架二探 (Prism vs MvvmCross)

    在上一篇Xamarin开发环境及开发框架初探中,曾简单提到MvvmCross这个Xamarin下的开发框架.最近又评估了一些别的,发现老牌Mvvm框架Prism现在也支持Xamarin Forms了, ...

  5. Xamarin.Forms+Prism(1)—— 开发准备

    本次随笔连载,主要用于记录本人在项目中,用Xamarin.Forms开发APP中所使用的第三方技术或一些技巧. 准备: 1.VS2017(推荐)或VS2015: 2.JDK 1.8以上: 3.Xama ...

  6. Xamarin.Forms+Prism(3)—— 简单提示UI的使用

    这次给大家介绍两个比较好用的提示插件,如成功.等待.错误提示. 准备: 1.新建一个Prism Xamarin.Forms项目: 2.右击解决方案,添加NuGet包: 1)Acr.UserDialog ...

  7. 老司机学新平台 - Xamarin Forms开发框架之MvvmCross插件精选

    在前两篇老司机学Xamarin系列中,简单介绍了Xamarin开发环境的搭建以及Prism和MvvmCross这两个开发框架.不同的框架,往往不仅仅使用不同的架构风格,同时社区活跃度不同,各种功能模块 ...

  8. 走进 Visual Studio Mobile Center for Xamarin.Forms

    前几篇分别介绍了 Xamarin.Forms 的 MVVM 的 Prism,UITest,Nuint Test,那这样算下来,代码部分基本结构都有了(逻辑就先忽略吧) 那接下来就应该是自动 Build ...

  9. Xamarin.Forms 开发资源集合(复制)

    复制:https://www.cnblogs.com/mschen/p/10199997.html 收集整理了下 Xamarin.Forms 的学习参考资料,分享给大家,稍后会不断补充: UI样式 S ...

随机推荐

  1. Python爬虫初学(三)—— 模拟登录知乎

    模拟登录知乎 这几天在研究模拟登录, 以知乎 - 与世界分享你的知识.经验和见解为例.实现过程遇到不少疑问,借鉴了知乎xchaoinfo的代码,万分感激! 知乎登录分为邮箱登录和手机登录两种方式,通过 ...

  2. 对于JavaScript中this关键字的理解

    这是我第二遍学this了,第一遍学的懵懵的.this指哪里都是凭我一个男人的直觉然后控制台输出看看对不对. 刚查了书.博客.视频.理解差不多了.毕竟菜鸡me: 一.首先介绍下什么是this this是 ...

  3. 黑科技:纯CSS定制文本省略

    作者:weilong,腾讯 web前端开发 工程师 商业转载请联系腾讯WeTest获得授权,非商业转载请注明出处. WeTest导读 拿到设计MM的设计稿,Oh NO,点点点后面又双叒叕加内容了,弹丸 ...

  4. Coursera scala课程第一周答案

    Exercise 1: Pascal's Triangle The following pattern of numbers is called Pascal's triangle. 1 1 1 1 ...

  5. Orleans例子再进一步

    Orleans例子再进一步 这是Orleans系列文章中的一篇.首篇文章在此 步骤 现在我想再添加一个方法,到IGrains项目内,这个方法里面有个延迟3秒,然后返回一个Task<string& ...

  6. 位图索引(Bitmap Index)的故事

    您如果熟悉Oracle数据库,我想您对Thomas Kyte的大名一定不会陌生.Tomas主持的asktom.oracle.com网站享誉Oracle界数十年,绝非幸致.最近在图书馆借到这位Oracl ...

  7. Servlet 服务器端小程序

    1.tomcat安装及目录介绍 JAVA_HOME CATALINA_HOME PATH=%JAVA_HOME%/bin;2.静态web项目.动态web项目 WEB-INF lib classes w ...

  8. 关于《Unity3D/2D游戏开发从0到1》书籍再版说明

    关于<Unity3D/2D游戏开发从0到1>第一版本在2015年7月1日全国发行,累计得到不少国内高校教师.培训机构的好评.但是由于Unity官方对于技术不断的升级与版本的快速迭代,基于U ...

  9. 简单聊天室(java版)

    这是本人从其他地方学习到的关于聊天室的一个模本,我从中截取了一部分关于客户端和服务端通信的Socket的内容.希望对大家对socket有个了解,我写的这些代码可以实现两人或多人在多台电脑上实现简单的对 ...

  10. Struts2学习笔记(二)——配置详解

    1.Struts2配置文件加载顺序: default.properties(默认常量配置) struts-default.xml(默认配置文件,主要配置bean和拦截器) struts-plugin. ...