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

    前言

    系列目录

    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 - 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.

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

    写在最后

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

  • 相关阅读:
    为什么会决定进行分库分表,分库分表过程中遇到什么难题,如何解决的?
    MySQL主从复制什么原因会造成不一致,如何预防及解决?
    PyQt5(2)、垃圾分类小程序(2)——初代窗口程序可执行文件
    垃圾分类小程序(1)——实现查找垃圾的类别
    python上的数据库sqlite3——插入多行数据
    pandas.DataFrame——pd数据框的简单认识、存csv文件
    Beautiful Soup 4.2.0 doc_tag、Name、Attributes、多值属性
    第一个爬虫——豆瓣新书信息爬取
    Decorator——Python初级函数装饰器
    正则表达式——字符类、分支条件、分组
  • 原文地址:https://www.cnblogs.com/GuZhenYin/p/7680425.html
Copyright © 2011-2022 走看看