C#使用Xamarin开发可移植移动应用目录
源码地址:https://github.com/l2999019/DemoApp
可以Star一下,随意 - -
呃 也有半个月没更新了. 本来这篇的Demo早就写完了,文章也构思好了.迟迟没发布..是因为实在太忙..
项目要上线..各种 你们懂的..
正赶上自己十一人生大事..结婚..所以..忙的那叫一个脚不沾地啊.
使用我们前面所学的技术,写一个增删改查.
效果如下:
废话不多说,直接开始吧.
列表ListView,采用继承重写的方式,实现简易的下拉刷新
采用HttpClient的方式访问后端的WebAPI.
使用了一系列的Xamarin提供的插件.
采用了MVVM的方式,来编写我们的业务代码.
前面我们说过,我们访问的是后端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/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() > 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/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() > 0)
- {
- return true;
- }
- return false;
- }
- }
- }
就是编写一个访问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;
- }
- }
详解请查看系列目录中的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
我们创建一个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.
至此,就完成了整个的简易增删改查的编写.
本系列到此,就已经进行了一大半了..后面会继续更新一些安卓库的绑定等内容,敬请期待.
来源: http://www.cnblogs.com/GuZhenYin/p/7680425.html