前言

系列目录

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. 微信小程序view标签以及display:flex的测试

    一:testview.wxml,testview.js自动生成示例代码 //testview.wxml <view class="section"> <view ...

  2. 201521123034 《Java程序设计》第3周学习总结

    1. 本章学习总结 看不清点这个:http://naotu.baidu.com/file/c01303326572f7916e506ec5f55270a4 2. 书面作业 1.代码阅读 public ...

  3. 201521123075 《Java程序设计》第9周学习总结

    1. 本周学习总结 2. 书面作业 本次PTA作业题集异常 1.常用异常 题目5-1 1.1 截图你的提交结果(出现学号) 1.2 自己以前编写的代码中经常出现什么异常.需要捕获吗(为什么)?应如何避 ...

  4. tsst

    import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Sc ...

  5. C# 泛型集合

    原文出处我的wiki,转载请说明出处 考虑到泛型在集合类型中的广泛应用,这里一起讨论. 1. 泛型 1.1 泛型的定义与约束 创建泛型方法.委托.接口或类时,需要在名称后增加尖括号及其中的泛型参数,泛 ...

  6. RSA原理、ssl认证、Tomcat中配置数字证书以及网络传输数据中的密码学知识

      情形一:接口的加.解密与加.验签 rsa不是只有加密解密,除此外还有加签和验签.之前一直误以为加密就是加签,解密就是验签.这是错误的! 正确的理解是: 数据传输的机密性:公钥加密私钥解密是密送,保 ...

  7. IDEA导入Eclipse项目 【未结束的注释、非法类型的开始、缺少符号】

    如果我们导入Eclipse项目的使用出现了未结束的注释.非法类型的开始.缺少符号这么一些编译时期的错误,而我们的代码明明看起来就是正常的-. 我们去检查一下是否编码的问题:把FileEncoding全 ...

  8. Mysql的基本命令图

    如果看不清的,右键图片在新标签页打开! 这是经过我的整理出来的!如果有重要的再补充把-..

  9. 源码跟读,Spring是如何解析和加载xml中配置的beans

    Spring版本基于: 跟踪代码源码基于: https://github.com/deng-cc/KeepLearning commit id:c009ce47bd19e1faf9e07f12086c ...

  10. 关于memcached的那些事儿

    一.前言 目前,memcached + mysql的这种存储组合,被广泛地应用到“读多写少”的应用场景上.那么在使用memcached的时候,我们需要注意哪些问题呢? 下面我们来探讨下使用memcac ...