C#使用Xamarin开发可移植移动应用进阶篇(10.综合演练,来一份增删改查CRUD)

说点什么..

呃 也有半个月没更新了. 本来这篇的Demo早就写完了,文章也构思好了.迟迟没发布..是因为实在太忙..

项目要上线..各种  你们懂的..

正赶上自己十一人生大事..结婚..所以..忙的那叫一个脚不沾地啊.

今天的学习内容?

使用我们前面所学的技术,写一个增删改查.

效果如下:

 

 

正文

废话不多说,直接开始吧.

1.采用了的技术

   列表ListView,采用继承重写的方式,实现简易的下拉刷新

   采用HttpClient的方式访问后端的WebAPI.

   使用了一系列的Xamarin提供的插件.

   采用了MVVM的方式,来编写我们的业务代码.

2.WebAPI

   前面我们说过,我们访问的是后端WebAPI,内容很简单..就是一个增删改查.

   多余的我就不多说了,直接贴出代码如下:

    public class ValuesController : ApiController{        

// GET api/values  
       [HttpGet]      
       
public List<ContextTable> Get(int page,int count){  
           
using (Models.School_TestEntities entites = new Models.School_TestEntities()){            
            
var date= entites.ContextTable.OrderBy(c => c.ID).Skip((page - 1) * count).Take(count).ToList();                return date;}                    
       }    
       
// PUT api/values/5public bool UpdateDate(Models.ContextTable datemodel){           // var date = JsonConvert.DeserializeObject<Models.ContextTable>(value);using (Models.School_TestEntities entites = new Models.School_TestEntities()){                var model = entites.ContextTable.Where(a => a.ID == datemodel.ID).FirstOrDefault();model.Title = datemodel.Title;model.AddTime = datemodel.AddTime;model.Context = datemodel.Context;                if (entites.SaveChanges() > 0){                    return true;}                return false;}}      
 
public bool AddDate(Models.ContextTable model){            var date = model;    
       
using (Models.School_TestEntities entites = new Models.School_TestEntities()){entites.ContextTable.Add(date);                if (entites.SaveChanges() >0){                  
 
return true;}}            return false;}        // DELETE api/values/5public bool Delete(int id){            using (Models.School_TestEntities entites = new Models.School_TestEntities()){                var date = entites.ContextTable.Where(a => a.ID == id).FirstOrDefault();entites.ContextTable.Remove(date);                if (entites.SaveChanges() > 0){                、
   
return true;}        
     
return false;}}}


3.编写服务仓储

就是编写一个访问WebAPI用的仓储.代码如下:

  public class ContextDataStore{HttpClient client;      
  
string RestUrl = "http://192.168.3.74:53470/api/values";  
     
public ContextDataStore(){client = new HttpClient();client.MaxResponseContentBufferSize = 256000;}      

     
public async Task<bool> AddItemAsync(ContextModel item){            var uri = new Uri(RestUrl+ "/AddDate/");            var json = JsonConvert.SerializeObject(item);var content = new StringContent(json);content.Headers.ContentType = new MediaTypeHeaderValue("application/json");      
     
var response = await client.PostAsync(uri, content);   if (response.IsSuccessStatusCode){                var date = await response.Content.ReadAsStringAsync();                return Convert.ToBoolean(date);}          
  
return false;}      

 
public async Task<bool> UpdateItemAsync(ContextModel item){          
            
var uri = new Uri(RestUrl + "/UpdateDate/");            var json = JsonConvert.SerializeObject(item);var content = new StringContent(json);content.Headers.ContentType = new MediaTypeHeaderValue("application/json");  
         
var response = await client.PostAsync(uri, content);          
         
if (response.IsSuccessStatusCode){              
  
var date = await response.Content.ReadAsStringAsync();                return Convert.ToBoolean(date);}      
            
return false;}      
     
       
public async Task<bool> DeleteItemAsync(int id){            var uri = new Uri(string.Format(RestUrl + "/Delete/?id=" + id, string.Empty));        
           
var response = await client.DeleteAsync(uri);             if (response.IsSuccessStatusCode){          
            
var content = await response.Content.ReadAsStringAsync();                return Convert.ToBoolean(content);}          
           
return false;}      
     
       
public async Task<IEnumerable<ContextModel>> GetItemsAsync(int page,int rows){          
 
var uri = new Uri(string.Format(RestUrl+"/Get/?page="+page+ "&count=" + rows, string.Empty));          
 
var response = await client.GetAsync(uri);List<ContextModel> Items = new List<ContextModel>();      
     
if (response.IsSuccessStatusCode){              
 
var content = await response.Content.ReadAsStringAsync();      
             
try{Items = JsonConvert.DeserializeObject<List<ContextModel>>(content);}          
               
catch (Exception ex){}}            return Items;}}


 

4.编写ViewModel来与界面进行绑定交互

详解请查看系列目录中的MVVM篇

代码如下(注释中有解释):


 public class ContextViewModel: INotifyPropertyChanged{        //初始化仓储public ContextDataStore DataStore =new ContextDataStore();        //设置绑定对象public ObservableCollection<ContextModel> Items { get; set; }    

   
//设置刷新命令public Command LoadItemsCommand { get; set; }  
     
public event PropertyChangedEventHandler PropertyChanged;      private int page = 1;    
       
private int rows = 10;      
       
/// <summary>/// 初始化各种数据与监听      
        
/// </summary>public  ContextViewModel(){Items = new ObservableCollection<ContextModel>();LoadItemsCommand = new Command(async () => await ExecuteLoadItemsCommand());        
    
//监听添加的消息MessagingCenter.Subscribe<ContextModelPage, ContextModel>(this, "AddItem", async (obj, item) =>{                var _item = item as ContextModel;                var date = await DataStore.AddItemAsync(_item);                if (date){LoadDate();          
          
await obj.DisplayAlert("提示", "添加成功!", "关闭");       await obj.Navigation.PopAsync();}          
               
else{                
await obj.DisplayAlert("提示", "添加失败!", "关闭");}});            //监听更新的消息MessagingCenter.Subscribe<ContextModelPage, ContextModel>(this, "UpdateItem", async (obj, item) =>{                var date = await DataStore.UpdateItemAsync(item);                if (date){LoadDate();                    await obj.DisplayAlert("提示", "修改成功!", "关闭");                    await obj.Navigation.PopAsync();}                else{                    await obj.DisplayAlert("提示", "修改失败!", "关闭");}});ExecuteLoadItemsCommand();}      
       
/// <summary>/// 删除的方法      
       
/// </summary>/// <param name="id"></param>/// <returns></returns>public async Task<bool> DeleteItem(int id){            var date = await DataStore.DeleteItemAsync(id);        
   
if (date){              
 
var item = Items.Where(a => a.ID == id).FirstOrDefault();Items.Remove(item);OnPropertyChanged("Items");}            return date;}      
       
/// <summary>/// 加载数据的命令      
       
/// </summary>/// <returns></returns>async Task ExecuteLoadItemsCommand(){          try{                //Items.Clear();var items = await DataStore.GetItemsAsync(page,rows);                foreach (var item in items){Items.Add(item);}OnPropertyChanged("Items");page++;}            catch (Exception ex){}}        

/// <summary>/// 重新刷新数据      
/// </summary>private async void LoadDate(){Items.Clear();page = 1;          
 
var items = await DataStore.GetItemsAsync(page, rows);        
    
foreach (var item in items){Items.Add(item);}OnPropertyChanged("Items");page++;}      

 
protected virtual void OnPropertyChanged(string propertyName){            if (PropertyChanged != null){PropertyChanged(this,                    new PropertyChangedEventArgs(propertyName));}}}


嗯.还是说明一下 这个ViewModel就类似于MVC中的控制器,起到一个承上启下的作用.与页面交互并把这些交互信息传递给仓储,由仓储来访问WebAPI

5.编写界面,绑定数据

我们创建一个ContentPage页面如下:

<?xml version="1.0" encoding="utf-8" ?><ContentPage xmlns="http://xamarin.com/schemas/2014/forms"xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"xmlns:local="clr-namespace:DemoApp.HTTPClientDemo.ViewModels"xmlns:Controls="clr-namespace:DemoApp.HTTPClientDemo;" x:Class="DemoApp.HTTPClientDemo.ListViewPage"><ContentPage.ToolbarItems><ToolbarItem Text="添加"  Order="Default" Clicked="ToolbarItem_Clicked"   /></ContentPage.ToolbarItems><ContentPage.Content><StackLayout><Controls:MyListView ItemsSource="{Binding Items}"VerticalOptions="FillAndExpand"HasUnevenRows="true"LoadMoreCommand="{Binding LoadItemsCommand}"x:Name="listdate"><ListView.ItemTemplate><DataTemplate ><ViewCell><ViewCell.ContextActions><MenuItem  CommandParameter="{Binding}" Clicked="MenuItem_Clicked" Text="修改"   /><MenuItem x:Name="DeleteBtn"  CommandParameter="{Binding ID}" Clicked="MenuItem_Clicked_1" Text="删除" IsDestructive="True" /></ViewCell.ContextActions><StackLayout Padding="10"><Label Text="{Binding Title}"LineBreakMode="NoWrap"Style="{DynamicResource ListItemTextStyle}"FontSize="16"/><Label Text="{Binding AddTime}"LineBreakMode="NoWrap"Style="{DynamicResource ListItemDetailTextStyle}"FontSize="13"/></StackLayout></ViewCell></DataTemplate></ListView.ItemTemplate></Controls:MyListView></StackLayout></ContentPage.Content></ContentPage>

这个ContentPage中,我们使用了StackLayout布局,ListView,ToolbarItem 等控件.绑定了我们前面编写的ContextViewModel(后台代码绑定的,在下面)

编写这个ContentPage的后台代码如下:

 public partial class ListViewPage : ContentPage{ContextViewModel viewModel;        public ListViewPage(){InitializeComponent();            this.BindingContext = viewModel = new ContextViewModel();}        private void MenuItem_Clicked(object sender, EventArgs e){            var mi = ((MenuItem)sender);ContextModel date = mi.CommandParameter as ContextModel;Navigation.PushAsync(new ContextModelPage());MessagingCenter.Send<ListViewPage,ContextModel>(this, "GetModel", date);}        private async void MenuItem_Clicked_1(object sender, EventArgs e){            var mi = ((MenuItem)sender);            int id = Convert.ToInt32( mi.CommandParameter);            var date = await viewModel.DeleteItem(id);            if (!date){              await  DisplayAlert("提示", "删除失败,请检查网络", "确定");}}        private void ToolbarItem_Clicked(object sender, EventArgs e){Navigation.PushAsync(new ContextModelPage());}}

这里,我们绑定了ContextViewModel,然后编写了界面上的各种交互事件.

以上,我们的列表也就算完成了,下面我们来看看我们的增加和修改页面.(也就是显示详细数据的页面)

如下:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"x:Class="DemoApp.HTTPClientDemo.ContextModelPage"><ContentPage.Content><StackLayout><Label Text="标题:" /><Entry Placeholder="请输入标题" x:Name="titel" /><Label Text="时间:"  /><DatePicker Format="yyyy-MM-dd" x:Name="times" /><Label Text="内容:"  /><Editor  HorizontalOptions="FillAndExpand" HeightRequest="200" x:Name="contexts" /><Button Text="保存" x:Name="BtnSave" Clicked="BtnSave_Clicked" ></Button></StackLayout></ContentPage.Content></ContentPage>

这里我们采用了前面系列中讲过的Label ,Entry,DatePicker ,Editor ,编写后台代码如下:

 public partial class ContextModelPage : ContentPage{private int isUpdate = 0;public ContextModelPage(){InitializeComponent();MessagingCenter.Subscribe<ListViewPage, ContextModel>(this, "GetModel", (obj, item) => {//DisplayAlert("提示", "传过来的参数为" + item, "确定");this.times.Date = item.AddTime.Value;this.titel.Text = item.Title;this.contexts.Text = item.Context;isUpdate = item.ID;});}private void BtnSave_Clicked(object sender, EventArgs e){if (isUpdate>0){ContextModel model = new ContextModel();model.AddTime = times.Date;model.Context = contexts.Text;model.Title = titel.Text;model.ID = isUpdate;MessagingCenter.Send(this, "UpdateItem", model);}else{ContextModel model = new ContextModel();model.AddTime = times.Date;model.Context = contexts.Text;model.Title = titel.Text;MessagingCenter.Send(this, "AddItem", model);}}protected override void OnDisappearing(){MessagingCenter.Unsubscribe<ListViewPage, ContextModel>(this, "GetModel");base.OnDisappearing();}}


这里,我们编写页面的点击等交互事件,然后我们采用通讯中心(MessagingCenter)的方式来传递修改和删除的信息给后台的ViewModel. 

至此,就完成了整个的简易增删改查的编写. 

写在最后

本系列到此,就已经进行了一大半了..后面会继续更新一些安卓库的绑定等内容,敬请期待.

相关文章: 

  • C#使用Xamarin开发可移植移动应用(1.入门与Xamarin.Forms页面),附源码

  • .NET Standard@Xamarin.Forms

  • C#使用Xamarin开发可移植移动应用(2.Xamarin.Forms布局,本篇很长,注意)附源码

  • C#使用Xamarin开发可移植移动应用(3.Xamarin.Views控件)附源码

  • C#使用Xamarin开发可移植移动应用(4.进阶篇MVVM双向绑定和命令绑定)附源码

  • C#使用Xamarin开发可移植移动应用(5.进阶篇显示弹出窗口与通讯中心)附源码

  • C#使用Xamarin开发可移植移动应用进阶篇(6.使用渲染器针对单个平台自定义控件),附源码

  • C#使用Xamarin开发可移植移动应用进阶篇(7.使用布局渲染器,修改默认布局),附源码

  • C#使用Xamarin开发可移植移动应用进阶篇(8.打包生成安卓APK并精简大小),附源码

  • C#使用Xamarin开发可移植移动应用进阶篇(9.混淆代码,防止反编译)

原文地址:http://www.cnblogs.com/GuZhenYin/p/7680425.html


.NET社区新闻,深度好文,微信中搜索dotNET跨平台或扫描二维码关注

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/323244.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

nssl1259-sequence【组合数,差分】

正题 题目大意 操作(l,r,k)(l,r,k)(l,r,k)表示 l∼rl\sim rl∼r这段区间&#xff0c;对于每个iii&#xff0c;加上Ckik−lC_k^{ik-l}Ckik−l​ 解题思路 我们可以发现对于一个全是1的序列&#xff0c;求kkk次前缀和&#xff0c;就是杨辉三角的第k1k1k1列&#xff0c;那么对于…

hexo部署在码云出现样式问题

然而本地服务器并没有任何问题 重建一个 重新建一个仓库 还是这种情况&#xff0c;回头再找原因&#xff0c;两次都是这种情况&#xff0c;就是配置错了 借用 https://blog.csdn.net/xiangwanpeng/article/details/53155642 https://blog.csdn.net/qq_29347295/article/deta…

当你输入一个网址的时候,实际会发生什么?

转载自 当你输入一个网址的时候&#xff0c;实际会发生什么? 译文:http://igoro.com/archive/what-really-happens-when-you-navigate-to-a-url/ 作为一个软件开发者&#xff0c;你一定会对网络应用如何工作有一个完整的层次化的认知&#xff0c;同样这里也包括这些应用所…

SIMD via C#

简介 TL;DR 我们为C#&#xff08;准确地说是.NET Core&#xff09;引入了一套全新的机制&#xff0c;使得C# 以后可以像C/C 一样直接使用intrinsic functions 来直接操作Intel CPU 的大多数SIMD 指令了&#xff08;从SSE 到AVX2&#xff09;。 &#xff08;注意是以后&#xff…

ssl提高组周三备考赛【2018.10.31】

前言 呆学校呆3天依旧不想复习期中&#xff0c;感觉要凉。 成绩 RankRankRankPersonPersonPersonScoreScoreScoreAAABBBCCC1112017myself2017myself2017myself1801801801001001008080800002222014yqf2014yqf2014yqf1401401400004040401001001004442017lw2017lw2017lw808080000…

Ae做一个立体地球

Ae做一个立体地球 拿到一张照片 将它变成标题的地球 在AE里 即可变成一个地球 看上去亮多了&#xff0c;再定个关键帧即可旋转

ASP.NET Core 处理 404 Not Found

问题 在没有修改任何配置的情况下&#xff0c;这是用户使用 Chrome 访问不存在的URL时会看到的内容&#xff1a; 幸运的是&#xff0c;处理错误状态代码非常简单&#xff0c;我们将在下面介绍三种技术。 解决方案 在以前的ASP.NET MVC版本中&#xff0c;主要在 web.config 中处…

搞定所有的跨域请求问题

转载自 搞定所有的跨域请求问题 网上各种跨域教程&#xff0c;各种实践&#xff0c;各种问答&#xff0c;除了简单的 jsonp 以外&#xff0c;很多说 CORS 的都是行不通的&#xff0c;老是缺那么一两个关键的配置。本文只想解决问题&#xff0c;所有的代码经过亲自实践。 本文…

nssl1269-射击【贪心,堆】

正题 题目大意 有n个东西&#xff0c;东西必须在aisa_i\ sai​ s前破坏&#xff0c;破坏后可以获得wiw_iwi​价值&#xff0c;求最大价值。 解题思路 我们可以将时间从大到小排序&#xff0c;然后用堆&#xff0c;每次处理价值最大的就好了。 code #include<cstdio> #…

搭建一个二次元博客

小叙&#xff1a; 因为前段日子尝试过自己搭建网站&#xff0c;也在b站发了视频&#xff0c;奈何技术太菜&#xff0c;被喷的严重。所以决定重构一下网站&#xff0c;改成一个个人博客。这里非常感谢小游提供的主题&#xff0c;感谢他对这么优秀的主题的推广。 如果你正好也要…

jar包天天见,可是你知道它的运行机制吗

转载自 jar包天天见&#xff0c;可是你知道它的运行机制吗 今天介绍两个大家每天都在用但是却很少去了解它的知识点&#xff1a;spi 和 jar 运行机制&#xff0c;废话不多说&#xff0c;开始正题。 spi spi 是 Java 提供的一套用来被第三方实现或者扩展的 API &#xff0c;…

nssl1270-创世纪【树形dp,基环树】

正题 题目大意 每个物品有一个可以限制的物品&#xff0c;要求一个集合内所有的物品都有一个不在集合内物品限制。求这个集合可以保护的最多物品 解题思路 类似没有上司的舞会 其实就是在基环树森林&#xff0c;我们可以利用二次树形dp的方法。 先找到环&#xff0c;然后强行…

从头编写 asp.net core 2.0 web api 基础框架 (5) EF CRUD

Github源码地址&#xff1a;https://github.com/solenovex/Building-asp.net-core-2-web-api-starter-template-from-scratch 这是第一大部分的最后一小部分。要完成CRUD的操作。 Repository Pattern 我们可以直接在Controller访问DbContext&#xff0c;但是可能会有一些问题: …

做这个网站原因之二

讲讲我最近干了什么事吧以及以后该干啥 其实大部分我学到的东西&#xff0c;都写在博客上了&#xff0c;可以通过博客看到一个人的学习轨迹。除了这些&#xff0c;我也尝试拍些视频去学习一些新的东西。视频剪辑&#xff0c;特效什么的都在尝试。 有个视频我也只是随便尝试尝试…

ssl提高组周四备考赛【2018.11.1】

前言 呆学校呆4天依旧不想复习期中&#xff0c;期中考凉透了。 成绩 RankRankRankPersonPersonPersonScoreScoreScoreAAABBBCCC1112014lyk2014lyk2014lyk2002002001001001007070703030302222017wyc2017wyc2017wyc1801801801001001008080800003332017xjq2017xjq2017xjq17017017…

spring cloud+dotnet core搭建微服务架构:配置中心续(五)

前言 上一章最后讲了&#xff0c;更新配置以后需要重启客户端才能生效&#xff0c;这在实际的场景中是不可取的。由于目前Steeltoe配置的重载只能由客户端发起&#xff0c;没有实现处理程序侦听服务器更改事件&#xff0c;所以还没办法实现彻底实现这一功能。这一章的例子&…

聊聊最近吧

讲讲我最近干了什么事吧以及以后该干啥 其实大部分我学到的东西&#xff0c;都写在博客上了&#xff0c;可以通过博客看到一个人的学习轨迹。除了这些&#xff0c;我也尝试拍些视频去学习一些新的东西。视频剪辑&#xff0c;特效什么的都在尝试。 有个视频我也只是随便尝试尝试…

C# 实现虚拟数字人

随着Ai技术的提升和应用&#xff0c;虚拟数字人被广泛应用到各行各业中。为我们的生活和工作提供了非常多的便利和色彩。 通过设置虚拟数字人的位置大小&#xff0c;可以让数字人可以在电脑屏幕各个位置显示&#xff1a; 虚拟数字人素材&#xff1a; 虚拟数字人(实际有语音&am…

AspectCore.Extension.Reflection : .NET Core反射扩展库

在从零实现AOP的过程中&#xff0c;难免会需要大量反射相关的操作&#xff0c;虽然在.net 4.5/.net core中反射的性能有了大幅的优化&#xff0c;但为了追求极致性能&#xff0c;自己实现了部分反射的替代方案&#xff0c;包括构造器调用、方法调用、字段读写&#xff0c;属性读…

P2468-[SDOI2010]粟粟的书架【主席树,二维前缀和】

正题 评测记录:https://www.luogu.org/recordnew/lists?uid52918&pidP2468 题目大意 对于每一个询问&#xff0c;求一个区域内最少取多少个数使它们的和不小于a。 解题思路 我们肯定取最大的 对于前50%的数据&#xff0c;用 sumi,j,ksum_{i,j,k}sumi,j,k​表示(1,1)(1,…