前言

系列目录

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

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

可以Star一下,随意 - -

说点什么..

呃 也有半个月没更新了. 本来这篇的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 - ) * count).Take(count).ToList();
return date;
} } // PUT api/values/5
public 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() > )
{
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() >)
{
return true;
} }
return false;
}
// DELETE api/values/5
public 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() > )
{
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 = ;
}
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 = ;
private int rows = ; /// <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 = ;
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开发可移植移动应用进阶篇(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. Java GUI+mysql+分页查询

    1.要求 : 创建一个学生信息管理数据库 2.实现分页查询 代码如下: a)学生实体类: /** * @author: Annie * @date:2016年6月23日 * @description: ...

  2. 团队作业4——第一次项目冲刺(Alpha版本)2017.4.27

    2017.04.27 天气阴沉 小雨. 时间:上午 9:35 ---10:10分 地点:陆大314实验室 会议内容:每天充分利用好大课间的时间,今天对昨天的的细节问题进行了讨论及方法更正.时间不等人这 ...

  3. 【Alpha阶段】第四次scrum meeting

    一.会议照片 二.会议内容 姓名 学号 负责模块 昨日任务完成度 今日任务 杨爱清 099 界面设计和交互功能 完成 百度合适的背景图片 杨立鑫 100 数据库搭建和其他 完成 开始编辑数据库 林 钊 ...

  4. 201521123053《Java程序设计》第1周学习总结

    1. 本周学习总结 第一次接触Java,让我感到很吃力,有些困难.但我知道接触所有新事物都会困难,慢慢来就好. 下面是我这周的学习总结: one  第一节课 老师上课太快了,而且我没预习,根本跟不上 ...

  5. 201521123006 《java程序设计》 第11周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 2. 书面作业 本次PTA作业题集多线程 1.互斥访问与同步访问 完成题集4-4(互斥访问)与4-5(同步访问) ...

  6. evak购物车-课程设计(201521123034陈凯欣)

    1.团队课程设计博客链接 https://i.cnblogs.com/EditPosts.aspx?postid=7047127 2.个人负责模块或任务说明 1.Java 编写商品类Goods,商品属 ...

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

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多流与文件相关内容. 2. 书面作业 将Student对象(属性:int id, String name,int age,doubl ...

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

    1. 本周学习总结 以你喜欢的方式(思维导图.OneNote或其他)归纳总结多网络相关内容. 2. 书面作业 1. 网络基础 1.1 比较ping www.baidu.com与ping cec.jmu ...

  9. 201521123066 《Java程序设计》第九周学习总结

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

  10. php memcache 扩展 php -m 与 phpinfo() 不同

    事情起因,因要升级 openssl(openssl升级这里不表) ,所以在升级后对 php 也进行了从新编译,编译成功. 发现没有安装,memcache 扩展,从新编译安装了一下,显示的安装成功,但是 ...