前言

系列目录

C#使用Xamarin开发可移植移动应用目录

源码地址:https://github.com/l2999019/DemoApp

可以Star一下,随意 - -

说点什么..

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

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

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

今天的学习内容?

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

效果如下:

正文

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

1.采用了的技术

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

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

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

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

2.WebAPI

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

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

  1. public class ValuesController : ApiController
  2. {
  3. // GET api/values
  4. [HttpGet]
  5. public List<ContextTable> Get(int page,int count)
  6. {
  7. using (Models.School_TestEntities entites = new Models.School_TestEntities())
  8. {
  9. var date= entites.ContextTable.OrderBy(c => c.ID).Skip((page - ) * count).Take(count).ToList();
  10. return date;
  11. }
  12.  
  13. }
  14.  
  15. // PUT api/values/5
  16. public bool UpdateDate(Models.ContextTable datemodel)
  17. {
  18. // var date = JsonConvert.DeserializeObject<Models.ContextTable>(value);
  19. using (Models.School_TestEntities entites = new Models.School_TestEntities())
  20. {
  21. var model = entites.ContextTable.Where(a => a.ID == datemodel.ID).FirstOrDefault();
  22. model.Title = datemodel.Title;
  23. model.AddTime = datemodel.AddTime;
  24. model.Context = datemodel.Context;
  25.  
  26. if (entites.SaveChanges() > )
  27. {
  28. return true;
  29. }
  30. return false;
  31.  
  32. }
  33.  
  34. }
  35.  
  36. public bool AddDate(Models.ContextTable model)
  37. {
  38. var date = model;
  39. using (Models.School_TestEntities entites = new Models.School_TestEntities())
  40. {
  41. entites.ContextTable.Add(date);
  42. if (entites.SaveChanges() >)
  43. {
  44. return true;
  45. }
  46.  
  47. }
  48. return false;
  49. }
  50. // DELETE api/values/5
  51. public bool Delete(int id)
  52. {
  53. using (Models.School_TestEntities entites = new Models.School_TestEntities())
  54. {
  55. var date = entites.ContextTable.Where(a => a.ID == id).FirstOrDefault();
  56. entites.ContextTable.Remove(date);
  57. if (entites.SaveChanges() > )
  58. {
  59. return true;
  60. }
  61. return false;
  62.  
  63. }
  64. }
  65. }

3.编写服务仓储

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

  1. public class ContextDataStore
  2. {
  3. HttpClient client;
  4. string RestUrl = "http://192.168.3.74:53470/api/values";
  5. public ContextDataStore()
  6. {
  7. client = new HttpClient();
  8. client.MaxResponseContentBufferSize = ;
  9. }
  10. public async Task<bool> AddItemAsync(ContextModel item)
  11. {
  12. var uri = new Uri(RestUrl+ "/AddDate/");
  13. var json = JsonConvert.SerializeObject(item);
  14. var content = new StringContent(json);
  15. content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
  16. var response = await client.PostAsync(uri, content);
  17.  
  18. if (response.IsSuccessStatusCode)
  19. {
  20. var date = await response.Content.ReadAsStringAsync();
  21. return Convert.ToBoolean(date);
  22.  
  23. }
  24. return false;
  25. }
  26.  
  27. public async Task<bool> UpdateItemAsync(ContextModel item)
  28. {
  29.  
  30. var uri = new Uri(RestUrl + "/UpdateDate/");
  31. var json = JsonConvert.SerializeObject(item);
  32. var content = new StringContent(json);
  33. content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
  34. var response = await client.PostAsync(uri, content);
  35.  
  36. if (response.IsSuccessStatusCode)
  37. {
  38. var date = await response.Content.ReadAsStringAsync();
  39. return Convert.ToBoolean(date);
  40.  
  41. }
  42. return false;
  43. }
  44.  
  45. public async Task<bool> DeleteItemAsync(int id)
  46. {
  47. var uri = new Uri(string.Format(RestUrl + "/Delete/?id=" + id, string.Empty));
  48. var response = await client.DeleteAsync(uri);
  49.  
  50. if (response.IsSuccessStatusCode)
  51. {
  52. var content = await response.Content.ReadAsStringAsync();
  53. return Convert.ToBoolean(content);
  54.  
  55. }
  56. return false;
  57. }
  58.  
  59. public async Task<IEnumerable<ContextModel>> GetItemsAsync(int page,int rows)
  60. {
  61. var uri = new Uri(string.Format(RestUrl+"/Get/?page="+page+ "&count=" + rows, string.Empty));
  62. var response = await client.GetAsync(uri);
  63. List<ContextModel> Items = new List<ContextModel>();
  64.  
  65. if (response.IsSuccessStatusCode)
  66. {
  67. var content = await response.Content.ReadAsStringAsync();
  68. try
  69. {
  70. Items = JsonConvert.DeserializeObject<List<ContextModel>>(content);
  71. }
  72. catch (Exception ex)
  73. {
  74.  
  75. }
  76.  
  77. }
  78. return Items;
  79. }
  80.  
  81. }

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

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

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

  1. public class ContextViewModel: INotifyPropertyChanged
  2. {
  3. //初始化仓储
  4. public ContextDataStore DataStore =new ContextDataStore();
  5.  
  6. //设置绑定对象
  7. public ObservableCollection<ContextModel> Items { get; set; }
  8. //设置刷新命令
  9. public Command LoadItemsCommand { get; set; }
  10.  
  11. public event PropertyChangedEventHandler PropertyChanged;
  12.  
  13. private int page = ;
  14. private int rows = ;
  15.  
  16. /// <summary>
  17. /// 初始化各种数据与监听
  18. /// </summary>
  19. public ContextViewModel()
  20. {
  21. Items = new ObservableCollection<ContextModel>();
  22. LoadItemsCommand = new Command(async () => await ExecuteLoadItemsCommand());
  23.  
  24. //监听添加的消息
  25. MessagingCenter.Subscribe<ContextModelPage, ContextModel>(this, "AddItem", async (obj, item) =>
  26. {
  27.  
  28. var _item = item as ContextModel;
  29. var date = await DataStore.AddItemAsync(_item);
  30.  
  31. if (date)
  32. {
  33. LoadDate();
  34. await obj.DisplayAlert("提示", "添加成功!", "关闭");
  35. await obj.Navigation.PopAsync();
  36. }
  37. else
  38. {
  39. await obj.DisplayAlert("提示", "添加失败!", "关闭");
  40. }
  41.  
  42. });
  43.  
  44. //监听更新的消息
  45. MessagingCenter.Subscribe<ContextModelPage, ContextModel>(this, "UpdateItem", async (obj, item) =>
  46. {
  47.  
  48. var date = await DataStore.UpdateItemAsync(item);
  49.  
  50. if (date)
  51. {
  52. LoadDate();
  53. await obj.DisplayAlert("提示", "修改成功!", "关闭");
  54. await obj.Navigation.PopAsync();
  55. }
  56. else
  57. {
  58. await obj.DisplayAlert("提示", "修改失败!", "关闭");
  59. }
  60.  
  61. });
  62. ExecuteLoadItemsCommand();
  63. }
  64.  
  65. /// <summary>
  66. /// 删除的方法
  67. /// </summary>
  68. /// <param name="id"></param>
  69. /// <returns></returns>
  70. public async Task<bool> DeleteItem(int id)
  71. {
  72. var date = await DataStore.DeleteItemAsync(id);
  73. if (date)
  74. {
  75. var item = Items.Where(a => a.ID == id).FirstOrDefault();
  76. Items.Remove(item);
  77. OnPropertyChanged("Items");
  78. }
  79. return date;
  80. }
  81.  
  82. /// <summary>
  83. /// 加载数据的命令
  84. /// </summary>
  85. /// <returns></returns>
  86. async Task ExecuteLoadItemsCommand()
  87. {
  88.  
  89. try
  90. {
  91. //Items.Clear();
  92. var items = await DataStore.GetItemsAsync(page,rows);
  93. foreach (var item in items)
  94. {
  95. Items.Add(item);
  96. }
  97. OnPropertyChanged("Items");
  98. page++;
  99. }
  100. catch (Exception ex)
  101. {
  102.  
  103. }
  104. }
  105.  
  106. /// <summary>
  107. /// 重新刷新数据
  108. /// </summary>
  109. private async void LoadDate()
  110. {
  111. Items.Clear();
  112. page = ;
  113. var items = await DataStore.GetItemsAsync(page, rows);
  114. foreach (var item in items)
  115. {
  116. Items.Add(item);
  117. }
  118. OnPropertyChanged("Items");
  119. page++;
  120. }
  121. protected virtual void OnPropertyChanged(string propertyName)
  122. {
  123.  
  124. if (PropertyChanged != null)
  125. {
  126. PropertyChanged(this,
  127. new PropertyChangedEventArgs(propertyName));
  128. }
  129. }
  130. }

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

5.编写界面,绑定数据

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

  1. <?xml version="1.0" encoding="utf-8" ?>
  2. <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
  3. xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
  4. xmlns:local="clr-namespace:DemoApp.HTTPClientDemo.ViewModels"
  5. xmlns:Controls="clr-namespace:DemoApp.HTTPClientDemo;"
  6. x:Class="DemoApp.HTTPClientDemo.ListViewPage">
  7. <ContentPage.ToolbarItems>
  8. <ToolbarItem Text="添加" Order="Default" Clicked="ToolbarItem_Clicked" />
  9. </ContentPage.ToolbarItems>
  10. <ContentPage.Content>
  11. <StackLayout>
  12. <Controls:MyListView
  13. ItemsSource="{Binding Items}"
  14. VerticalOptions="FillAndExpand"
  15. HasUnevenRows="true"
  16. LoadMoreCommand="{Binding LoadItemsCommand}"
  17. x:Name="listdate"
  18. >
  19.  
  20. <ListView.ItemTemplate>
  21.  
  22. <DataTemplate >
  23. <ViewCell>
  24. <ViewCell.ContextActions>
  25. <MenuItem CommandParameter="{Binding}" Clicked="MenuItem_Clicked" Text="修改" />
  26. <MenuItem x:Name="DeleteBtn" CommandParameter="{Binding ID}" Clicked="MenuItem_Clicked_1" Text="删除" IsDestructive="True" />
  27. </ViewCell.ContextActions>
  28. <StackLayout Padding="10">
  29. <Label Text="{Binding Title}"
  30. LineBreakMode="NoWrap"
  31. Style="{DynamicResource ListItemTextStyle}"
  32. FontSize="16"/>
  33. <Label Text="{Binding AddTime}"
  34. LineBreakMode="NoWrap"
  35. Style="{DynamicResource ListItemDetailTextStyle}"
  36. FontSize="13"/>
  37. </StackLayout>
  38. </ViewCell>
  39. </DataTemplate>
  40. </ListView.ItemTemplate>
  41. </Controls:MyListView>
  42. </StackLayout>
  43. </ContentPage.Content>
  44. </ContentPage>

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

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

  1. public partial class ListViewPage : ContentPage
  2. {
  3. ContextViewModel viewModel;
  4. public ListViewPage()
  5. {
  6. InitializeComponent();
  7. this.BindingContext = viewModel = new ContextViewModel();
  8. }
  9.  
  10. private void MenuItem_Clicked(object sender, EventArgs e)
  11. {
  12. var mi = ((MenuItem)sender);
  13. ContextModel date = mi.CommandParameter as ContextModel;
  14. Navigation.PushAsync(new ContextModelPage());
  15. MessagingCenter.Send<ListViewPage,ContextModel>(this, "GetModel", date);
  16. }
  17.  
  18. private async void MenuItem_Clicked_1(object sender, EventArgs e)
  19. {
  20. var mi = ((MenuItem)sender);
  21. int id = Convert.ToInt32( mi.CommandParameter);
  22. var date = await viewModel.DeleteItem(id);
  23. if (!date)
  24. {
  25. await DisplayAlert("提示", "删除失败,请检查网络", "确定");
  26. }
  27. }
  28.  
  29. private void ToolbarItem_Clicked(object sender, EventArgs e)
  30. {
  31. Navigation.PushAsync(new ContextModelPage());
  32. }
  33. }

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

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

如下:

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

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

  1. public partial class ContextModelPage : ContentPage
  2. {
  3. private int isUpdate = 0;
  4. public ContextModelPage()
  5. {
  6. InitializeComponent();
  7. MessagingCenter.Subscribe<ListViewPage, ContextModel>(this, "GetModel", (obj, item) => {
  8.  
  9. //DisplayAlert("提示", "传过来的参数为" + item, "确定");
  10. this.times.Date = item.AddTime.Value;
  11. this.titel.Text = item.Title;
  12. this.contexts.Text = item.Context;
  13. isUpdate = item.ID;
  14. });
  15. }
  16.  
  17. private void BtnSave_Clicked(object sender, EventArgs e)
  18. {
  19. if (isUpdate>0)
  20. {
  21.  
  22. ContextModel model = new ContextModel();
  23. model.AddTime = times.Date;
  24. model.Context = contexts.Text;
  25. model.Title = titel.Text;
  26. model.ID = isUpdate;
  27. MessagingCenter.Send(this, "UpdateItem", model);
  28.  
  29. }
  30. else
  31. {
  32.  
  33. ContextModel model = new ContextModel();
  34. model.AddTime = times.Date;
  35. model.Context = contexts.Text;
  36. model.Title = titel.Text;
  37. MessagingCenter.Send(this, "AddItem", model);
  38. }
  39.  
  40. }
  41.  
  42. protected override void OnDisappearing()
  43. {
  44. MessagingCenter.Unsubscribe<ListViewPage, ContextModel>(this, "GetModel");
  45. base.OnDisappearing();
  46. }
  47. }

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

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

写在最后

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

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

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

    前言 系列目录 C#使用Xamarin开发可移植移动应用目录 源码地址:https://github.com/l2999019/DemoApp 可以Star一下,随意 - - 说点什么.. 本篇..基 ...

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

    前言 系列目录 C#使用Xamarin开发可移植移动应用目录 源码地址:https://github.com/l2999019/DemoApp 可以Star一下,随意 - - 说点什么.. 本篇..基 ...

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

    前言 系列目录 C#使用Xamarin开发可移植移动应用目录 源码地址:https://github.com/l2999019/DemoApp 可以Star一下,随意 - - 说点什么.. 嗯,前面讲 ...

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

    前言 系列目录 C#使用Xamarin开发可移植移动应用目录 源码地址:https://github.com/l2999019/DemoApp 可以Star一下,随意 - - 说点什么.. 今天讲讲如 ...

  5. Online Coding开发模式 (通过在线配置实现一个表模型的增删改查功能,无需写任何代码)

    JEECG 智能开发平台. 开发模式由代码生成器转变为Online Coding模式                      (通过在线配置实现一个表模型的增删改查功能,无需一行代码,支持用户自定义 ...

  6. Android,java,php开发最基本的知识,mysql sqlite数据库的增删改查代理,sql语句

    作者:程序员小冰,CSDN博客:http://blog.csdn.net/qq_21376985转载请说明出处. 下面是代码: 增加:insert into 数据表(字段1,字段2,字段3) valu ...

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

    前言 系列目录 C#使用Xamarin开发可移植移动应用目录 源码地址:https://github.com/l2999019/DemoApp 可以Star一下,随意 - - 说点什么.. 嗯..前面 ...

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

    前言 系列目录 C#使用Xamarin开发可移植移动应用目录 源码地址:https://github.com/l2999019/DemoApp 可以Star一下,随意 - - 说点什么.. 嗯..前面 ...

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

    前言 系列目录 C#使用Xamarin开发可移植移动应用目录 源码地址:https://github.com/l2999019/DemoApp 可以Star一下,随意 - - 说点什么.. 没啥好说的 ...

随机推荐

  1. 软工+C(2017第6期) 最近发展区/脚手架

    // 上一篇:工具和结构化 // 下一篇:野生程序员 教育心理学里面有提到"最近发展区"这个概念,这个概念是前苏联发展心理学家维果茨基(Vygotsky)提出的,英文名词是Zone ...

  2. 四则运算题目生成程序(基于控制台)(Bug修改)

    针对上个程序中出现的bug进行修改 https://git.coding.net/cx873230936/calculator.git Bug: 1.控制台输入问题数问题 a.不能处理用户输入负数. ...

  3. spring的list ,set,map,properties注入(set,get注入)

    ①Message.java: package com.hts.entity; import java.io.Serializable; import java.util.List; import ja ...

  4. 201521123006 《Java程序设计》第6周学习总结

    1. 本周学习总结 1.1 面向对象学习暂告一段落,请使用思维导图,以封装.继承.多态为核心概念画一张思维导图,对面向对象思想进行一个总结. 注1:关键词与内容不求多,但概念之间的联系要清晰,内容覆盖 ...

  5. 201521123088《java程序与设计》第9周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常相关内容. 2. 书面作业 1. 常用异常 题目5-1 1.1 截图你的提交结果(出现学号) 1.2 自己以前编写的代码中经常出 ...

  6. 201521123034《Java程序设计》第十周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常与多线程相关内容. 2. 书面作业 本次PTA作业题集异常.多线程 1.finally 题目4-2 1.1 截图你的提交结果(出 ...

  7. 201521123038 《Java程序设计》 第十一周学习总结

    201521123038 <Java程序设计> 第十一周学习总结 1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 2. 书面作业 本次PTA作业题集多 ...

  8. 201521123015 《Java程序设计》第13周学习总结

    1. 本周学习总结 2. 书面作业 1. 网络基础 1.1 比较ping www.baidu.com与ping cec.jmu.edu.cn,分析返回结果有何不同?为什么会有这样的不同? IP地址不同 ...

  9. Ansible系列(六):各种变量定义方式和变量引用

    本文目录:1.1 ansible facts1.2 变量引用json数据的方式 1.2.1 引用json字典数据的方式 1.2.2 引用json数组数据的方式 1.2.3 引用facts数据1.3 设 ...

  10. dynamics 365 AI 解决方案 —— 微软布局

    核心提示:微软在 Office365.Azure 云.Dynamics365 上进行人工智能技术的部署,野心不小. 微软在2016年9月宣布组建自己的 AI 研究小组.该小组汇集了超过 5000 名计 ...