您的位置:首页 > 编程语言 > C#

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

2017-10-18 00:00 666 查看


说点什么..

呃 也有半个月没更新了. 本来这篇的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/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;

           }
       }
   }



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跨平台或扫描二维码关注

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐