30天学通C#项目案例开发
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

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对象实例,这是单件模式的核心。