Windows Phone中使用Local DataBase与ISolateStorage—在MVVM模式下(二)

    在Windows Phone中使用Local DataBase与ISolateStorage—在MVVM模式下(—)中我们已经完成了三件事情,包括:

一.新建MVVMLight的Windows Phone Project
二.在Model中建立SQL CE数据库
三.建立MessageView.xaml界面以及绑定MessageViewModel

 

 

    下面我们继续添加IM功能…….

四.添加SendMessage的功能

    上文我们已经设计了MessageView.xaml,并绑定了MsgViewModel,下一步我们在MessageViewModel中添加几个属性,分别来对应View中的输入框和ListBox消息列表。消息输入框绑定的属性很简单,如下,   

   1: private string sendmessage;
   2: public string SendMessage
   3: {
   4:     get { return sendmessage; }
   5:     set { 
   6:         if(value!=null)
   7:         {
   8:             sendmessage=value;
   9:             RaisePropertyChanged("SendMessage");                
  10:         }
  11:     }
  12: }

 

     RaisePropertyChanged("SendMessage");是用来通知binding值已经改变,是MVVMLight封装的,与 我们UserInfoTable Class中自己实现的NotifyPropertyChanged基本一致。

   1: #region NotifyPropertyChanged
   2:  
   3: public event PropertyChangedEventHandler PropertyChanged;
   4: private void NotifyPropertyChanged(string propertyname)
   5: {
   6:     if(PropertyChanged!=null)
   7:     {
   8:         PropertyChanged(this,new PropertyChangedEventArgs(propertyname));
   9:     
  10:     }
  11:  
  12: }
  13:  #endregion

 

    至于绑定ListBox的源,我们要使用ObservableCollection<UserInfoTable> ,这里之所以不使用List<UserInfoTable>或者IEnumerable<UserInfoTable>,是因为在绑定ListBox时如果我们ItemSource改变了或者重新实例化后,List或者IEnumerable可以实现ListBox刷新,但是如果仅仅ListBox中的一个Item发生改变,这时候List就不能满足要求了,有人说UserTable不是实现INotifyPropertyChanged,INotifyPropertyChanging,作为Item的UserTable改变时是可以刷新ListBox的,嗯,这点是对的,但是如果List/IEnumerable添加值或者删除值的时候,Listbox是得不到更新的通知的。

这时候我们就要用到ObservableCollection了,当然Item也要实现INotifyPropertyChanged等接口才可以。看下面代码:

   1: private ObservableCollection<UserInfoTable> userTable=new ObservableCollection<UserInfoTable>();
   2:  
   3: public ObservableCollection<UserInfoTable> UserTable
   4: {
   5:     get{return this.userTable; }
   6:     set {
   7:         if (value != null)
   8:         {
   9:             userTable = value;
  10:             RaisePropertyChanged("UserTable");
  11:         }
  12:     }
  13: }

    还有一个注意的问题,RaisePropertyChanged("UserTable")中的UserTable不要错写成usertable即不要写成字段,否则会引起调试失败。

这时候我们就可以为我们的Send Message按钮添加Command了。在MessageViewModel中新建

   1: publicICommandSendMessageCommand{get;privateset;}

注:WPF中实现MVVM模式Command是立下了汗马功劳。当然ICommand要引用using System.Windows.Input命名空间。


 

    然后在MessageViewModel的构造函数中注册SendMessageCommand的Execute事件。首先引用命名空间

using GalaSoft.MvvmLight.Command;我们需要用到其中的RelayCommand,以及lamda表达式(当然,在其中使用函数调用也可以)。代码如下所示:
   1:  
   2:             SendMessageCommand = new RelayCommand(            
   3:                 ()=>{
   4:                     UserInfoTable userinfo = new UserInfoTable();
   5:                     userinfo.UserId = 1;
   6:                     userinfo.UserNameAndTime = "Haisa";
   7:                     userinfo.UserMessage = sendmessage;
   8:                     userTable.Add(userinfo);
   9:                     haisaDataContext.HaisaTable.InsertOnSubmit(userinfo);
  10:                     haisaDataContext.SubmitChanges();
  11:                 }       
  12:             );
现在我们在ViewModel中已经定义了Command,然后使用Blend绑定Send Message按钮和SendMessageCommand,如下图示,拖动Behaviours中的InvokeCommandAction拖动到Send Message按钮上,然后在右侧属性窗口上设置InvokeCommandAction的属性进行设置:

WHD8UUKS)TE3%Z70F`V]OE9


 

H3$]6W(~4)S1H0@PJ$E)%3R


 

如上图,该程序我们只需要设置EventName为Click即可。

     OK,到这里我们已经设置好SendMessage按钮的响应事件了,我们接着看SendMessageCommand的Execute事件。我们实例化了一个

UserInfoTable Class,然后使 userinfo.UserMessage = sendmessag,然后Add至ObservableCollection,这时候就可以在ListBox中更新已发送的消息,我们还想将发送的Message存储为历史记录,即每次打开程序可以查看历史记录的内容,这时候便要使用本地数据库了。 在构造函数中实例化haisaDataContext = new HaisaDataContext(HaisaDataContext.DBConnectionString);然后在SendMessageCommand中就可使用Linq进行数据库Insert:
   1: haisaDataContext.HaisaTable.InsertOnSubmit(userinfo);
   2:  haisaDataContext.SubmitChanges();
注意一定要使用SubmitChanges函数才能真正的执行数据库写入操作。 当然这只是简单的模拟Send Message,过段时间我会使用Socket实现真正的往服务器端发送Message。^_^

我们还希望能查看发送Message的历史记录,这时候为ApplicationBarIconButton添加Click事件,在事件中加入导航至MessageHistoryView的代码,ApplicationBarIconButton貌似没法绑定Command,我们就直接在BehindCode中添加事件如下了:

   1: this.NavigationService.Navigate(new Uri("/View/MessageView.xaml", UriKind.RelativeOrAbsolute));

五.添加MessageHistoryView的页面功能

      MessageHistoryView中只添加一个ListBox和一个返回SendMessageView的ApplicationBarIconButton。MessageHistoryView中绑定ListBox的方式与MessageView中类似,只不过Command的执行代码改成读取Local DataBase SQL CE了。

如下所示:

   1: ShowMessageHistoryCommand=new RelayCommand(
   2:         ()=>{
   3:              
   4:             IEnumerable<UserInfoTable> users=from p in haisaDataContext.HaisaTable select p;              
   5:             userTable = new ObservableCollection<UserInfoTable>(users);
   6:         
   7:         }
   8:         );

      因为每个View绑定ViewModel的时候,都会实例化一个ViewModel类,所以此时多个View绑定同一个ViewModel是不会相互影响的,因为真正绑定的其实是ViewModel的多个实例。

     这时候基本功能已经实现,但是用户体验真的好么?我们知道Windows Phone是有墓碑机制的,假使没有针对墓碑机制做一些处理,用户体验是相当糟糕的,下一篇开始讲解。

六.完善用户体验

Coming Soon…….

posted @ 2012-01-16 23:48  梦回千秋云断  阅读(566)  评论(2编辑  收藏  举报