2.5.4 保存联系人功能的实现
当用户单击“保存联系人”按钮时,会将用户的输入保存到名为MyFriends.xml的XML文件中。在保存联系人信息时,代码首先获取指定的文件路径,判断文件是否存在于指定的位置。如果存在,则追加数据;如果不存在,则创建一个新的XML文件再进行数据保存。下面首先看一看文件名存在时的代码。
代码位置:见光盘中本章源代码的Controls\ AddNewFriendControl.xaml.cs文件。
01 private void btnSave_Click(object sender, RoutedEventArgs e) 02 { 03 string xmlFilename = (string)Application. //获取保存的文件名 04 Current.Properties["SavedDetailsFileName"]; 05 string fullXmlPath = Path.Combine //获取完整的XML文件路径 06 (Environment.CurrentDirectory, xmlFilename); 07 bool allRequiredFieldsFilledIn = true; //判断所需要的字段是否填充 08 allRequiredFieldsFilledIn = IsEntryValid(txtFriendName) && 09 IsEntryValid(txtEmail); 10 //判断E-mail是否正确 11 allRequiredFieldsFilledIn = IsEmailValid(txtEmail.Text); 12 if (allRequiredFieldsFilledIn) //如果所填的资料都正确填入 13 { 14 if (File.Exists(fullXmlPath)) //如果也存在文件名 15 { 16 try 17 { 18 //如果当前没有XML且没有联系人在内存中,追加到文件 19 if (FriendsList.Instance().Count == 0) 20 { 21 Friend friend = new Friend 22 {//使用对象初始化语法初始化并给Friend对象赋值 23 ID = Guid.NewGuid(), 24 Name = friendContent.FriendName, 25 Email = friendContent.FriendEmail, 26 PhotoUrl = friendContent.PhotoUrl, 27 VideoUrl = friendContent.VideoUrl, 28 MusicUrl = friendContent.MusicUrl 29 }; 30 //调用XMLFileOperation的AppendToFile方法追加文件 31 XMLFileOperations.AppendToFile(fullXmlPath, friend); 32 FriendsList.Instance().Add(friend); //添加到联系人列表中 33 RaiseEvent(new RoutedEventArgs(FriendAddedEvent)); //引发路由事件 34 friendContent.Reset(); 35 this.Reset(); 36 MessageBox.Show("成功保存联系人"); 37 } 38 //否则只是更新内存中的联系人集合中的单个联系人 39 //在应用程序关闭时写入磁盘 40 else 41 { 42 FriendsList.Instance().Add(new Friend 43 { 44 ID = Guid.NewGuid(), 45 Name = friendContent.FriendName, 46 Email = friendContent.FriendEmail, 47 PhotoUrl = friendContent.PhotoUrl, 48 VideoUrl = friendContent.VideoUrl, 49 MusicUrl = friendContent.MusicUrl 50 }); 51 RaiseEvent(new RoutedEventArgs(FriendAddedEvent)); 52 friendContent.Reset(); 53 this.Reset(); 54 MessageBox.Show("成功保存联系人"); 55 } 56 } 57 catch 58 { 59 MessageBox.Show("更新联系人错误"); 60 } 61 }
● 第03~06行首先获取完整的所要保存的文件的文件名和路径信息。
● 第07~11行,将调用两个自定义的方法判断用户是否输入了文本域,以及用户输入的电子邮件是否正确。
● 第12行代码在所有要求输入的信息都成功填写之后,再开始进行保存的操作。
● 第14行代码判断是否存在XML文件名。如果存在,将执行下面的代码。
● 第18~36行代码判断如果在内存中不存在联系人集合,则初始化一个Friend对象并赋值,然后调用XMLFileOperations的AppendToFile方法,将联系人添加到XML文件中。再添加到FriendsList集合中,并触发了FriendAddedEvent的路由事件。第34行代码调用Reset方法重置字段的值,使其清空。第35行代码调用自定义的Reset方法重置控件的值,使其清空。最后弹出一个消息框。
● 第40~61行代码开始是判断如果联系人列表中存在联系人,将先添加一个Friend到FriendsList中。存在时将进行的是更新操作,这里没有调用XMLFileOperations类的方法,保存操作将在应用程序退出时完成。最后进行了重置,并触发FriendAddedEvent的路由事件。
前面的代码分析了“保存联系人”事件处理代码的前半部分。下面看一看后半部分的代码,用于处理当所要保存的文件名不存在时的情形,代码如下所示。
代码位置:见光盘中本章源代码的Controls\ AddNewFriendControl.xaml.cs文件。
01 else 02 {//如果不存在XML文件名,则创建一个新的文件并写入 03 try 04 { 05 Friend friend = new Friend 06 {//初始化Friend对象并赋值 07 ID = Guid.NewGuid(), 08 Name = friendContent.FriendName, 09 Email = friendContent.FriendEmail, 10 PhotoUrl = friendContent.PhotoUrl, 11 VideoUrl = friendContent.VideoUrl, 12 MusicUrl = friendContent.MusicUrl 13 }; 14 //调有CreateInitialFile写入一个新的文件 15 XMLFileOperations.CreateInitialFile(fullXmlPath, friend); 16 FriendsList.Instance().Add(friend); //添加到联系人集合 17 RaiseEvent(new RoutedEventArgs(FriendAddedEvent)); //触发事件 18 friendContent.Reset(); //重置对象 19 this.Reset(); //重置控件 20 MessageBox.Show("成功保存联系人"); 21 } 22 catch (Exception ex) 23 { 24 MessageBox.Show("保存联系人信息时产生错误"); 25 } 26 } 27 } 28 else 29 { 30 MessageBox.Show("需要填充所有的字段,或者是验证是否输入错误", 31 "错误", 32 MessageBoxButton.OK, 33 MessageBoxImage.Error); 34 } 35 }
● 第05~12行代码首先实例化一个Friend对象。
● 第15行代码调用XMLFileOperations的CreateInitialFile()方法来创建和保存XML文件。
● 第16~20行代码则添加联系人集合,触发事件并重置对象和事件,最后弹出消息框提示保存成功。
● 第22~35是异常处理和如果输入条件不满足时弹出的错误消息。
“保存联系人”按钮调用了几个自定义的方法来实现其功能,一个是验证输入框是否输入了值,一个是验证电子邮件地址是否正确,另外一个是重置控件的ReSet方法,这些方法的代码如下所示。
代码位置:见光盘中本章源代码的Controls\ AddNewFriendControl.xaml.cs文件。
01 private bool IsEntryValid(TextBox txtBox) 02 { //判断用户姓名字段是否输入为空,否则变换背景色 03 txtBox.Background = string.IsNullOrEmpty(txtBox.Text) ? 04 Brushes.Red : Brushes.White; 05 //返回是否为空的布尔值 06 return !string.IsNullOrEmpty(txtBox.Text); 07 } 08 private void Reset() 09 { //重置控件的值,使其返回初始化的为空状态 10 this.txtFriendName.Text = string.Empty; 11 this.txtEmail.Text = string.Empty; 12 this.photoSrc.Source = null; 13 this.videoSrc.Source = null; 14 this.musicSrc.Source = null; 15 txtMusic.Visibility = Visibility.Visible; 16 imgMusic.Visibility = Visibility.Hidden; 17 } 18 private bool IsEmailValid(string email) 19 { 20 bool isValid =false; 21 string pattern = //指定验证的正则表达式 22 @"^([a-zA-Z0-9_\-\.]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5})$"; 23 Regex regEx = new Regex(pattern); //实例化Regex对象 24 isValid = regEx.IsMatch(email); //进行验证工作 25 //根据验证的结果设置电子邮件框的背景色 26 txtEmail.Background = !isValid ? Brushes.Red : Brushes.White; 27 //返回验证结果的布尔值 28 return isValid; 29 }
● 第01~06行的IsEntryValid()方法判断指定的文本框是否为空。如果为空,则显示背景色为红色,并返回是否为空的布尔值。
● 第08~17行代码重置控件的值,使其返回初始化为空的状态。
● 第18~29行代码的IsEmailValid方法,将使用正则表达式判断指定的电子邮件是否正确。如果不正确,则将输入框显示为红色并返回验证结果的布尔值。
在添加联系人的窗体中,使用了FriendContent单件类来临时的保存联系人信息。之所以使用单件模式,与主窗口的3D动画有关,在主窗体中,分别放置了AddNewFriendControl控件和ViewAllUsersControl控件,而在用于3D动画的ItemsControl的DataTemplate中,又包含了AddNewFriendControl控件和ViewAllUsersControl这两个用户控件。为了确保数据在两个拷贝间的同步,引入了单件模式,FriendContent类的代码如下所示。
代码位置:见光盘中本章源代码的Helpers\ FriendContent.cs文件。
01 public class FriendContent 02 { //用于临时保存联系人信息的单件类 03 public string FriendName { get; set; } //名字 04 public string FriendEmail { get; set; } //电邮 05 public string PhotoUrl { get; set; } //照片路径 06 public string VideoUrl { get; set; } //视频路径 07 public string MusicUrl { get; set; } //音乐路径 08 private static FriendContent instance; //实例变量 09 private FriendContent() 10 { //私有构造函数,防止用户直接实例化 11 } 12 public void Reset() 13 { //调用Reset方法清空字段 14 FriendName = string.Empty; 15 FriendEmail = string.Empty; 16 PhotoUrl = string.Empty; 17 VideoUrl = string.Empty; 18 MusicUrl = string.Empty; 19 } 20 public static FriendContent Instance() 21 { //实例化FriendContent的公共静态方法 22 if (instance == null) 23 { 24 instance = new FriendContent(); 25 } 26 return instance; 27 } 28 }
● 第02~07行代码定义了联系人实体相关的属性。
● 第09~11行代码将类的构造函数私有化,防止用户直接通过构造函数实例化类。
● 第12~19行代码用于清空联系人属性。
● 第20~26行代码是一个公共静态方法,该方法将返回FriendContent对象实例,这是单件模式的核心。