Silverlight入门:第四部分 - 数据绑定

在之前的第三部分中,我们做了很多工作来获取公共Web服务返回的数据并让 其显示在控件中。我们已经用过了DataGrid控件,但它并不是我们真正想要的用 户界面,所以让我们自己来定义一个。为此,我们需要一个ItemsControl和一个 DataTemplate。这将让我们学习到XAML的绑定语法,以及如何利用更强大的数据 绑定信息。

在开始之前——先删除DataGrid

在开始之 前,让我们先删除并且只删除DataGrid,我们也不再需要它的程序集引用以及 xmlns,所以也可以大胆删除它们。

把DataGrid替换成ItemsControl,像 是这样:

1 <ItemsControl x:Name="SearchResults"  Margin="0,8,0,0" Grid.Row="1" />

这里我们又要用到 Blend了,我们准备在Blend中为ItemControl修改ItemTemplate。ItemControl本 质上只是一个按照我们要求工作的解析控件。如果我们仅仅只是把DataGrid替换 成ItemControl,那么我们将得到:

ItemControl不知道我们想如何显示数据,所以我们要在模板中告诉它 ……让我们回到Blend。通常我们都在这里编辑(前面说到过)。

在框中显示发布消息的用户的头像。使用我们之前学到的布局知识可 以很容易地创建模板。我们在Blend中放置一个ResultObjects并右击选择编辑 ItemTemplate(在已生成项目菜单下)。

现在我们已经获得了一个可以填充内容的空模板。在随后的对话框中,我把 它命名为SearchResultsTemplate。现在我们处于布局编辑模式,可以在其中拖 拉或移动内容。我创建了一个基于表格的布局,这是我的模板的XAML:

1   <DataTemplate  x:Key="SearchResultsTemplate">
2       <Grid  Margin="4,0,4,8" d:DesignWidth="446" d:DesignHeight="68">
3            <Grid.ColumnDefinitions>
4                <ColumnDefinition Width="Auto" />
5                <ColumnDefinition Width="*" />
6            </Grid.ColumnDefinitions>
7            <Border VerticalAlignment="Top" Margin="8" Padding="2"  Background="White">
8               <Image  Width="40" Height="40" />
9            </Border>
10
11         <StackPanel  Grid.Column="1" VerticalAlignment="Top" Margin="0,4,0,0">
12              <TextBlock x:Name="AuthorName"  FontWeight="Bold" />
13             <Grid  Margin="0,6,0,0">
14                  <Grid.RowDefinitions>
15                      <RowDefinition Height="Auto" />
16                      <RowDefinition Height="2" />
17                      <RowDefinition Height="Auto"  />
18                  </Grid.RowDefinitions>
19                  <TextBlock x:Name="TweetMessage" TextWrapping="Wrap" />
20                  <TextBlock  x:Name="PublishDateLabel" Grid.Row="2" />
21              </Grid>
22         </StackPanel>
23      </Grid>
24 </DataTemplate>

我们还把ItemControl放入了ScrollViewer中,因为它本身没有提供滚动条:

1 <ScrollViewer Grid.Row="2"  HorizontalScrollBarVisibility="Disabled"  VerticalScrollBarVisibility="Auto" BorderThickness="1">
2      <ItemsControl x:Name="SearchResults" Margin="0,8,0,0"  Grid.Row="1" ItemTemplate="{StaticResource SearchResultsTemplate}"  />
3 </ScrollViewer>

现在我们已经设置完控件了,但是我们还没有告诉它如何处理接收到的数据 。

XAML绑定语法

这里是我们写绑定语法的地方。你看,ItemsControl正在获取数据(记住, 我们没有改变代码,所以 SearchResults.ItemsSource仍然被设置为我们的 PagedCollectionView)。我们需要使用绑定来将实体元素映射到模板。基本的 XAML绑定语法是:

{Binding Path=<some-data-path>, Mode=<binding  mode>}

你还能得到更多高级的功能,但我们将从简单的开始。比如说,将模板中的 图像元素绑定到TwitterSearchResult模型的头像,看起来像这样:

1 <Image Width="40" Height="40" Source="{Binding  Path=Avatar, Mode=OneWay}" />

同时绑定作者到作者名称元素,像这样:

1 <TextBlock x:Name="AuthorName" FontWeight="Bold"  Text="{Binding Path=Author, Mode=OneWay}" />

我们将它们的模式设置成OneWay,因为在不需要改变数据的情况下不需要使 用TwoWay。在发布日期的处理上,我们需要提供一些明确的数据格式,这可以通 过值转换器做到。

绑定一个值转换器

值转换器是实现IValueConverter接口的一些类,它们提供了正向和反向的转 换方法。我们打算在发布日期上采用明确的日期对象格式,所以我们将在项目中 一个被叫做转换器的文件夹中创建一个名为DateTimeConverter.cs的类。这个类 看起来像这样:

1   using System;
2   using System.Threading;
3    using System.Windows.Data;
4
5   namespace  TwitterSearchMonitor.Converters
6   {
7         /*
8         * Use this converter for formatting  dates in XAML databinding
9         * Example:
10        * Text="{Binding Path=PublishDate, Converter= {StaticResource DateTimeFormatter}, ConverterParameter=MMM  yy}" />
11       *
12       * */
13      public class DateTimeConverter : IValueConverter
14      {
15         #region IValueConverter  Members
16
17         public object Convert(object  value, Type targetType, object parameter,  System.Globalization.CultureInfo culture)
18          {
19             DateTime? bindingDate = value as  DateTime?;
20
21             if (culture ==  null)
22             {
23                  culture = Thread.CurrentThread.CurrentUICulture;
24              }
25
26             if  (bindingDate != null)
27             {
28                  string dateTimeFormat = parameter as  string;
29                 return  bindingDate.Value.ToString(dateTimeFormat, culture);
30              }
31
32             return  string.Empty;
33         }
34
35          public object ConvertBack(object value, Type targetType, object  parameter, System.Globalization.CultureInfo culture)
36          {
37             throw new  NotImplementedException();
38         }
39
40          #endregion
41     }
42 }

我们要回到XAML页面来使用它(Search.xaml),还要为此添加xmlns声明和 资源。我们要使用的xmlns看起来像这样:

1 xmlns:converters="clr- namespace:TwitterSearchMonitor.Converters"

之后在XAML中的资源节中(其它模板被定义的地方),我们将为转换器添加 一个节点:

1 <navigation:Page.Resources>
2      <converters:DateTimeConverter  x:Key="DateTimeFormatter" />
3 ...

之后我们就能在PublishDateLabel元素上使用我们的转换器了,像这样:

1 <TextBlock x:Name="PublishDateLabel" Text="{Binding  Path=PublishDate,
2     Converter={StaticResource  DateTimeFormatter},
3     ConverterParameter=dd-MMM-yyyy  hh:mm tt}" Grid.Row="2" />

这将告诉XAML应该运行IValueConverter来得到输出。我们已经得到了想要的 精确的数据格式。所有这些用于绑定的额外语法,使我们得到了期望的解析结果 :

没错,我知道用twitpic作为搜索关键字获得了一些有趣的结果,但那是因为 用它作为搜索条件获得的数据刷新速度比较快!

很好,不是很难,不是吗?绑定语法对建设你的应用程序来说是至关重要的 。

存储一些设置和配置数据

存储最后一次登陆的TwitterID对我们的应用程序来说是很有用的功能,这样 当程序下一次启动的时候,就能从上次离开的地方继续。  此外,它还能保存 搜索条件历史,使我们可以在历史导航中查看。

为此,我们将使用Silverlight中的独立存储。它可以为存储简单数据开启一 个低信用度的用户区域。这里有更多关于独立存储的内容:

# 使用Silverlight中的独立存储

# 改变和增加独立存储配额要做到这一点,我将在Model文件夹中添加一个Helper类。这个辅助类将协助 我们在独立存储区域保存和读取数据。独立存储的基础是在其中创建一个文件, 并在需要的时候读取或写入数据。在我们的应用中,我们将用独立存储来保存键 值对数据(搜索条件/TwitterID)。以下是Helper.cs类的内容:

1   using System.IO.IsolatedStorage;
2
3    namespace TwitterSearchMonitor.Model
4   {
5        public class Helper
6       {
7            internal static string GetLatestTweetId(string searchTerm)
8            {
9               if  (IsolatedStorageSettings.ApplicationSettings.Contains(searchTerm)) 
10             {
11                  return IsolatedStorageSettings.ApplicationSettings [searchTerm].ToString();
12             }
13              else
14             {
15                  return "0";
16              }
17         }
18
19         internal  static void SaveLatestTweetId(string searchTerm, string  latestId)
20         {
21             if  (IsolatedStorageSettings.ApplicationSettings.Contains(searchTerm)) 
22             {
23                  IsolatedStorageSettings.ApplicationSettings[searchTerm] =  latestId;
24             }
25              else
26             {
27                  IsolatedStorageSettings.ApplicationSettings.Add (searchTerm, latestId);
28             }
29          }
30     }
31 }

现在在Search.xaml.cs中,我们将在活动指针被设置后在SearchForTweetsEx 中添加如下内容:

1 _lastId = Helper.GetLatestTweetId(SearchTerm.Text); //  get the latest ID from settings
2
3  Helper.SaveLatestTweetId(SearchTerm.Text, _lastId); // saving for  history even if a result isn't found

在OnReadCompleted中,当我们关闭XMLReader后,还要添加如下内容:

1 Helper.SaveLatestTweetId(SearchTerm.Text, _lastId); //saving  last tweet id

如果查找到搜索结果,则将查询条件和TwitterID存入独立存储。

总结

在本章节我们为控件设置了模板,并使用XAML语法绑定了一些简单的数据, 还为格式化视图中的信息添加了一个值转换器,最后还用独立存储机制保存了设 置信息。

现在我们的程序已经可以正常工作了,接下来让我们为它锦上添花。

posted @ 2011-09-07 14:13  Areas  阅读(348)  评论(0编辑  收藏  举报