IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    WP8.1开发:MVVM4:课程表应用

    编程小梦发表于 2014-10-25 15:39:07
    love 0

    今天小梦继续和大家分享一下MVVM之一个简单的课程表应用.其运行效果如图.没有设计UI,大家不要嫌弃.讲了记事本之后还要在讲这个课程表应用,有俩个原因.一个原因是让大家清楚ViewModel不一定是一个页面对应一个ViewModel,也可以是页面的一部分对应一个ViewModel.还有就是让大家熟悉下JSON的序列化和反序列化.所以这个课程表是使用json存储数据的.

    windows phone开发教程

    这个课程表和上一篇的记事本本质是一样的.所以小梦重点强调一下我们需要注意的细节和易错的地方:

      • DatePicker控件的Date属性是DateTimeOffset类型,TimePicker控件的Time属性是TimeSpan类型的.大家一定要注意.
      • 将默认的星期几转换为中文的星期一的方法是:return DateTimeFormatInfo.CurrentInfo.GetDayName(weak); weak是DayOfWeek类型
      • 我们如何建立课程表页面的ViewModel呢:
      • 我们知道,一周有七天,而这个七天的内容类型无非是一样的:今天的是星期几,今天有哪些课.所以我们可以单独把一周中的每一天单独抽取出来作为一个viewModel.这个ViewModel拥有Day和Courses属性,它们分别表示今天是星期几以及今天有哪些课.其代码如下:

    public class CourseTimetableColumnViewModel:ModelBase
        {
            public DayOfWeek Day { get; private set; }//星期
            public ObservableCollection Courses { get; private set; }//课程
            public CourseTimetableColumnViewModel(DayOfWeek day)
            {
    
                Day = day;
                Courses = new ObservableCollection(
                    from course in JsonCourseStore.Current.Courses
                    where course.Day == Day
                    orderby course.StartTime
                    select course
                    );
            }
    
        }

    那么整个课程表页面对应的ViewMode: CourseTimetableViewModel呢?很简单,它只需要一次建立周一到周日七个CourseTimetableColumnViewModel即可.这样CourseTimetableViewModel的内容就有了.根据我们之前记事本应用的经验.我们还需要增加课表,删除课表,修改课表3个命令.这样基本就可以算完了.但是为了更好的人性化,比如我们希望用户每次打开课表显示的都是今天的课程,那么我们应该怎么办呢:我们课表使用的是Pivot控件,而Pivot控件有一个SelectedIndex属性,表示的是当前选中的是哪一项.所以我们还需要在CourseTimetableViewModel再添加一个SelectCourseIndex属性,用来确保用户首次打开课表显示的是今天的课表.CourseTimetableViewModel完整代码如下:

    using Schedule.Command;
    using Schedule.Common;
    using Schedule.Models;
    using Schedule.Service;
    using Schedule.Views;
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace Schedule.ViewModels
    {
        public class CourseTimetableViewModel:ModelBase
        {
            public List CourseListViewModels { get; private set; }
    
            private int selectCourseIndex;
    
            public int SelectCourseIndex
            {
                get { return selectCourseIndex; }
                set
                { this.SetProperty(ref this.selectCourseIndex, value); }
            }
    
            public DelegateCommand AddCommand { get; set; }
            public DelegateCommand DeleteCommand { get; set; }
            public DelegateCommand EditCommand { get; set; }
            public CourseTimetableViewModel()
            {
    
                CourseListViewModels = new List();
                for (int i = 0; i < 7; i++)
                {
                    CourseListViewModels.Add(new CourseTimetableColumnViewModel((DayOfWeek)i));
                }
                selectCourseIndex = (int)DateTime.Today.DayOfWeek;
                AddCommand = new DelegateCommand(Add);
                DeleteCommand = new DelegateCommand(Delete);
                EditCommand = new DelegateCommand(Edit);
            }
            private void Add()
            {
                DayOfWeek day = CourseListViewModels[selectCourseIndex].Day;
                NavigationHelp.NavigateTo(typeof(NewOrEditCourse),day);
            }
    
            private void Delete(Object paramater)
            {
                Guid id = (Guid)paramater;
                var course = JsonCourseStore.Current.Courses.FirstOrDefault
                        (
                           c => c.ID == id
                        );
                CourseListViewModels[SelectCourseIndex].Courses.Remove(course);
                JsonCourseStore.Current.Delete(course);
    
            }
    
            private void Edit(Object paramater)
            {
                Guid id = (Guid)paramater;
                NavigationHelp.NavigateTo(typeof(NewOrEditCourse),id);
            }
        }
    }

    这样课表页面的ViewModel就介绍完了.下面再说一下json的序列化和反序列化.这个在林老师的<深入浅出windows phone 8.1>中有说明.我就直接上代码了:json的序列化和反序列就是那几行代码,一般只需要改变一下数据的类型就可以了.

    using Schedule.Models;
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Linq;
    using System.Runtime.Serialization.Json;
    using System.Text;
    using System.Threading.Tasks;
    using Windows.Storage;
    using System.IO;
    namespace Schedule.Service
    {
        public class JsonCourseStore
        {
            StorageFolder localFolder = ApplicationData.Current.LocalFolder;
            private static string JsonCourseName = "course.json";
            public ObservableCollection Courses//所有课程
            {
               get;
               set;
            }
    
            private static JsonCourseStore jsonCourseStore;//单例模式()
    
           public  static JsonCourseStore Current
           {
               get
               {
                   if (jsonCourseStore == null)
                   {
                      jsonCourseStore = new JsonCourseStore();
    
                   }
                   return jsonCourseStore;
               }
           }
    
           private JsonCourseStore()
           {
    
           }
    
            public async void Getdata()
            {
                await LoadCourseFromStorage();
            }
    
            public async Task Commit()//保存课表
            {
                var jsonSerializer = new DataContractJsonSerializer(typeof(ObservableCollection));
                using (var stream = await localFolder.OpenStreamForWriteAsync(JsonCourseName,
                    CreationCollisionOption.ReplaceExisting))
                {
                    jsonSerializer.WriteObject(stream, Courses);
                }
            }
    
            private async Task LoadCourseFromStorage()//读取课表
            {
    
                IReadOnlyList files = await localFolder.GetFilesAsync();
                bool isExist = files.Any(file => file.Name == JsonCourseName);
                if (isExist)
                {
                    using (var stream = await localFolder.OpenStreamForReadAsync(JsonCourseName))
                    {
                        var jsonSerializer = new DataContractJsonSerializer(typeof(ObservableCollection));
                        Courses = (ObservableCollection)jsonSerializer.ReadObject(stream);
                    }
                }
                else
                {
                    Courses = new ObservableCollection();
                }
            }
    
            public async void Add(Course Note)
            {
                Courses.Add(Note);
                await Commit();
            }
    
            public async void Delete(Course Note)
            {
                Courses.Remove(Note);
                await Commit();
            }
    
            public async void Modify(Course data)
            {
                var oldData = from n in Courses
                              where n.ID == data.ID
                              select n;
                Course course = oldData.FirstOrDefault();
                Courses.Remove(course);
                Courses.Add(data);
                await Commit();
            }
        }
    }

    最后还有俩点大家需要注意:

    • 注意我在增加修改课表页面的ViewModel与之前记事本应用的具体实现上的细节.
    • 注意我在课表页面删除,修改命令以及记事本应用的删除,修改命令的具体绑定方式

    下面的代码和记事本应用的区别就不大了,大家直接看源码吧.

    WP8.1课程表应用下载

     如果小梦的文章对你有帮助!欢迎支持小梦!



沪ICP备19023445号-2号
友情链接