天气查看器应用程序开发指南
1. 改变 ListBox 的 ItemsPanel 以水平排列项目
1.1 改变 ListBox 的 ItemsPanel
要改变 ListBox 的 ItemsPanel,需在 ListBox 元素中、ListBox.ItemTemplate 元素之前插入第 41 - 45 行代码。ListBox.ItemsPanel 元素会替换 ListBox 的默认 ItemsPanel,让你能指定 ListBox 中项目的排列方式。ListBox.ItemsPanel 元素包含一个 ItemsPanelTemplate 元素(第 42 - 44 行),用于指定 ListBox 元素的方向。第 43 行定义了一个 StackPanel,其 Orientation 属性设置为 Horizontal。
1.2 运行天气查看器应用程序
步骤如下:
1. 选择“Debug”>“Start Debugging”来运行应用程序。
2. 输入一个邮政编码,然后按下“Get Weather”按钮调用 Web 服务。
3. 输出结果应与示例类似。注意,结果返回可能需要几秒钟。此时,ListBox 项目现在是水平排列的,并且当项目无法一次性全部显示时,ListBox 仍会自动提供滚动条。
1.3 关闭应用程序
点击浏览器窗口的关闭框来关闭正在运行的应用程序。
2. 向应用程序添加用户控件
2.1 向应用程序添加新的用户控件
操作步骤如下:
1. 在解决方案资源管理器中右键单击 WeatherViewer 项目,选择“Add”>“New Item…”。
2. 选择 Silverlight 用户控件模板,并将文件命名为 WeatherDetailsView.xaml。
2.2 构建自定义控件
操作步骤如下:
1. 移除新用户控件的 Width 和 Height 属性,使控件能根据放置它的布局容器进行缩放。
2. 将 XAML 中的 Grid 元素替换为图 32.38 中第 4 - 34 行所示的元素。
2.3 显示所选日期的完整天气详情
2.3.1 布局设置
Grid 使用默认的一行一列,因此无需定义行或列。第 5 - 6 行创建了一个 Rectangle 控件,其 HorizontalAlignment 和 VerticalAlignment 属性设置为 Stretch,使 Rectangle 填充整个 Grid 单元格。Rectangle 的 Fill 属性指定其填充颜色为“Aquamarine”,Opacity 属性指定 Rectangle 应为半透明,该值范围是 0 到 1,0 表示完全透明,1 表示完全不透明。
Border 元素(第 7 - 33 行)包含了自定义控件中的所有其他元素。第 8 行引入了 BorderBrush 属性,用于指定边框的颜色,以及 BorderThickness 属性,用于控制边框的像素厚度。
第 10 - 32 行定义了一个垂直 StackPanel,它由一个 Image(第 11 - 12 行)、一个 TextBlock(第 13 - 15 行)、一个水平 StackPanel(第 16 - 30 行)和一个 Button(第 31 行)组成。Image 和 TextBlock 元素使用与 Page.xaml 中相同的设置。水平 StackPanel 包含用于显示特定日期温度信息的 TextBlocks。第 18、21、24 和 27 行显示温度值的标签。第 19 - 20、22 - 23、25 - 26 和 28 - 29 行显示温度值。在每个 TextBlock 中,使用 Binding 标记扩展来指定绑定到控件的 WeatherData 属性。实际的 WeatherData 对象作为此数据的源,将通过稍后设置此自定义控件的 DataContext 属性来指定。
最后,Button 对象(第 31 行)用于允许用户关闭自定义控件并返回主应用程序。在继续下一步之前,请务必保存项目。
2.3.2 添加关闭按钮的点击事件处理程序
操作步骤如下:
1. 在 WeatherDetailsView 的 XAML 中右键单击,选择“View Code”。
2. 在“Class Name ComboBox”中选择“closeButton”,然后从“Method Name ComboBox”中选择“Click”插入事件处理程序。
3. 按照图 32.39 所示格式化代码。
4. 插入第 13 行代码,当用户点击关闭按钮时,使用自定义控件的 Visibility 属性隐藏自定义控件。
2.4 添加 WeatherDetailsView 控件到 GUI
2.4.1 添加自定义控件的命名空间
要使用新控件,首先需要将第 2 行代码添加到 Page.xaml 中。这将创建一个名为 Weather 的 XML 命名空间,指示它代表项目中的 WeatherViewer 命名空间(项目名称是项目类的默认命名空间)。保存项目,使其识别新的命名空间。
2.4.2 插入 WeatherDetailsView 控件
将第 61 - 62 行代码插入到 Page.xaml 文件的主 Grid 中的最后一个元素位置。注意,我们指定了 Visibility 属性的值为 Collapsed,即控件是 GUI 的一部分,但当前不显示。同时,我们设置了 Grid.RowSpan 属性为 2,当该控件显示时,它将占据主 Grid 的两行。由于 WeatherDetailsView 控件配置为扩展以填充其容器的整个可用区域,当该控件显示时,它将完全覆盖 GUI 中的所有其他控件,从而防止用户在显示此 WeatherDetailsView 时访问 GUI 的其余部分。
2.5 添加 forecastListBox 的 SelectionChanged 事件处理程序
操作步骤如下:
1. 在 Page.xaml.vb 中,从“Class Name ComboBox”中选择“forecastListBox”,然后从“Method Name ComboBox”中选择“SelectionChanged”插入事件处理程序。
2. 按照图 32.42 所示格式化代码。
3. 插入第 82 - 88 行代码。第 82 行确定 ListBox 中是否有选定的项目。如果有,第 84 行将 WeatherDetailsView(completeDetails)的 DataContext 属性设置为 forecastList 中选定的项目。然后第 87 行使用 WeatherDetailsView 的 Visibility 属性显示该控件。
2.6 最终天气查看器应用程序代码
图 32.45 - 32.48 展示了天气查看器应用程序的完整源代码。本教程中学习的包含新编程概念的代码行已突出显示。
2.7 添加 TextBox 的 TextChanged 事件处理程序
操作步骤如下:
1. 在 Page.xaml.vb 中,从“Class Name ComboBox”中选择“inputTextBox”,然后从“Method Name ComboBox”中选择“TextChanged”插入事件处理程序。
2. 按照图 32.43 所示格式化代码。
3. 插入第 96 行代码,当用户开始输入另一个邮政编码时,清除 ListBox。当 ListBox 的 ItemsSource 属性设置为 Nothing 时,ListBox 中将不显示任何项目。
2.8 运行和关闭应用程序
2.8.1 运行应用程序
选择“Debug”>“Start Debugging”来运行应用程序。输入一个邮政编码,按下“Get Weather”按钮调用 Web 服务。一旦天气预报显示,点击预报中的某一天查看详细视图。浏览器窗口应与图 32.44 类似。注意,可以通过从 Page.xaml 中主 Grid 元素的开始标签中移除 ShowGridLines 属性(第 7 行)来消除用户界面上的虚线。
2.8.2 关闭应用程序
点击浏览器窗口的关闭框关闭正在运行的应用程序,然后点击 IDE 的关闭框关闭 IDE。
3. 代码示例
3.1 Page.xaml
<UserControl
x:Class="WeatherViewer.Page"
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid x:Name="LayoutRoot" Background="LightSkyBlue">
<Grid.RowDefinitions>
<RowDefinition Height="35" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="110" />
<ColumnDefinition Width="110" />
</Grid.ColumnDefinitions>
<Border Grid.Row="0" Grid.Column="0" CornerRadius="10" Background="LightGray" Margin="2">
<TextBlock Text="Weather Viewer" Padding="6" />
</Border>
<TextBox x:Name="inputTextBox" Grid.Row="0" Grid.Column="1" FontSize="18" Margin="4"/>
<Button x:Name="submitButton" Content="Get Weather" Grid.Row="0" Grid.Column="2" Margin="4" />
<ListBox x:Name="forecastList" Grid.Row="1" Margin="10">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Width="120" Orientation="Vertical" HorizontalAlignment="Center">
<Image Source="{Binding WeatherImage}" Margin="5" Width="55" Height="58"/>
<TextBlock Text="{Binding DayOfWeek}" TextAlignment="Center" FontSize="12" Margin="5" TextWrapping="Wrap"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Weather:WeatherDetailsView x:Name="completeDetails" Visibility="Collapsed" Grid.RowSpan="2"/>
</Grid>
</Grid>
</UserControl>
3.2 Page.xaml.vb
Partial Public Class Page
Inherits UserControl
' constructor
Public Sub New()
InitializeComponent()
End Sub ' New
' process submitButton's Click event
Private Sub submitButton_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles submitButton.Click
Dim zipcode As String = inputTextBox.Text ' get zipcode
Me.Cursor = System.Windows.Input.Cursors.Wait ' wait cursor
Dim forecastURL As String = "http://www.webservicex.net/WeatherForecast.asmx/" & "GetWeatherByZipCode?ZipCode=" & zipcode
' asynchronously invoke the web service
weatherService.DownloadStringAsync(New Uri(forecastURL))
End Sub ' submitButton_Click
' event handler to process weather forecast
Private Sub weatherService_DownloadStringCompleted(ByVal sender As Object, ByVal e As DownloadStringCompletedEventArgs) Handles weatherService.DownloadStringCompleted
If e.Error Is Nothing AndAlso e.Result.Contains("Day") Then
DisplayWeatherForecast(e.Result)
End If
Me.Cursor = System.Windows.Input.Cursors.Arrow ' arrow cursor
End Sub ' weatherService_DownloadStringCompleted
' display weather forecast
Private Sub DisplayWeatherForecast(ByVal xmlData As String)
' parse the XML data for use with LINQ
Dim weatherXML As XDocument = XDocument.Parse(xmlData)
' convert XML into WeatherData objects using XML literals
Dim weatherInformation = From item In weatherXML...<WeatherData> Where Not item.IsEmpty Select New WeatherData With {
.DayOfWeek = item.<Day>.Value,
.WeatherImage = item.<WeatherImage>.Value,
.MaxTemperatureF = Convert.ToInt32(item.<MaxTemperatureF>.Value),
.MinTemperatureF = Convert.ToInt32(item.<MinTemperatureF>.Value),
.MaxTemperatureC = Convert.ToInt32(item.<MaxTemperatureC>.Value),
.MinTemperatureC = Convert.ToInt32(item.<MinTemperatureC>.Value)
}
' bind forecastList.ItemsSource to the weatherInformation
forecastList.ItemsSource = weatherInformation
End Sub ' DisplayWeatherForecast
' Show details of the selected day
Private Sub forecastList_SelectionChanged(ByVal sender As Object, ByVal e As System.Windows.Controls.SelectionChangedEventArgs) Handles forecastList.SelectionChanged
If forecastList.SelectedItem IsNot Nothing Then
completeDetails.DataContext = forecastList.SelectedItem
completeDetails.Visibility = Windows.Visibility.Visible
End If
End Sub ' forecastList_SelectionChanged
' clear the Grid when the text in inputTextBox changes
Private Sub inputTextBox_TextChanged(ByVal sender As Object, ByVal e As System.Windows.Controls.TextChangedEventArgs) Handles inputTextBox.TextChanged
forecastList.ItemsSource = Nothing ' clear the ListBox
End Sub ' inputTextBox_TextChanged
End Class ' Page
3.3 WeatherDetailsView.xaml
<UserControl x:Class="WeatherViewer.WeatherDetailsView"
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<Rectangle HorizontalAlignment="Stretch" Fill="Aquamarine" VerticalAlignment="Stretch" Opacity="0.8" />
<Border CornerRadius="20" Background="AliceBlue" BorderBrush="Blue" BorderThickness="4" Width="400" Height="175">
<StackPanel>
<Image Source="{Binding WeatherImage}" Margin="5" Width="55" Height="58" />
<TextBlock Text="{Binding DayOfWeek}" Margin="5" TextAlignment="Center" FontSize="12" TextWrapping="Wrap" />
<StackPanel HorizontalAlignment="Center" Orientation="Horizontal">
<TextBlock Text="Max F:" Margin="5" FontSize="16"/>
<TextBlock Text="{Binding MaxTemperatureF}" Margin="5" FontSize="16" FontWeight="Bold"/>
<TextBlock Text="Min F:" Margin="5" FontSize="16"/>
<TextBlock Text="{Binding MinTemperatureF}" Margin="5" FontSize="16" FontWeight="Bold"/>
<TextBlock Text="Max C:" Margin="5" FontSize="16"/>
<TextBlock Text="{Binding MaxTemperatureC}" Margin="5" FontSize="16" FontWeight="Bold"/>
<TextBlock Text="Min C:" Margin="5" FontSize="16"/>
<TextBlock Text="{Binding MinTemperatureC}" Margin="5" FontSize="16" FontWeight="Bold"/>
</StackPanel>
<Button x:Name="closeButton" Content="Close" Width="80"/>
</StackPanel>
</Border>
</Grid>
</UserControl>
3.4 WeatherDetailsView.xaml.vb
Partial Public Class WeatherDetailsView
Inherits UserControl
Public Sub New()
InitializeComponent()
End Sub ' New
' close the details view
Private Sub closeButton_Click(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles closeButton.Click
Me.Visibility = Windows.Visibility.Collapsed
End Sub ' closeButton_Click
End Class ' WeatherDetailsView
4. 关键技能总结
4.1 创建 Silverlight 应用程序项目
步骤如下:
1. 在 Visual Studio 中,选择“File”>“New Project…”显示“New Project”对话框。
2. 在对话框中,在 Visual Basic Silverlight 项目类型下,选择“Silverlight Application”,命名项目,然后点击“OK”。
3. 在点击“OK”后出现的“Add Silverlight Application”对话框中,选择“Add a new Web to the solution for hosting this control”单选按钮,并从“Project Type ComboBox”中选择“Web Application Project”。
4.2 其他常见操作
| 操作 | 步骤 |
|---|---|
| 更改 Grid 的背景颜色 | 从 Background 属性中移除 White,然后按 Ctrl + Space 显示预定义颜色名称的菜单,从中选择一个值。也可以指定任何十六进制格式为 #RRGGBB 的颜色。 |
| 显示 Grid 中的网格线 | 在 Grid 元素的开始标签中插入 ShowGridLines 属性。 |
| 定义 Grid 中的行和列 | 创建 Grid.RowDefinitions 元素并在其中定义 RowDefinition 元素来定义行;创建 Grid.ColumnDefinitions 元素并在其中定义 ColumnDefinition 元素来定义列。 |
| 将控件放置在特定的 Grid 位置 | 在控件的开始标签中指定 Grid.Row 和 Grid.Column 属性,使用 Grid.RowSpan 或 Grid.ColSpan 使控件跨越多行或多列。 |
| 在控件周围放置边框 | 将控件放在 Border 元素内,并使用 Border 的属性(如 Background 和 CornerRadius)配置其样式。 |
| 显示文本 | 定义一个 TextBlock 元素并设置其 Text 属性。 |
| 指定控件的字体大小 | 将控件的 FontSize 属性设置为 WPF 像素值(每个像素为 1/96 英寸)。 |
| 以编程方式访问控件 | 定义控件的 x:Name 属性。 |
| 在 GUI 上放置按钮 | 定义一个 Button 元素并设置其 Content 属性,使用 Button 的 Click 事件响应用户按下按钮的操作。 |
| 使 Silverlight 应用程序在浏览器窗口中可调整大小 | 移除应用程序的 UserControl 元素的 Width 和 Height 属性。 |
| 使用 DataGrid 元素 | 双击工具箱中的 DataGrid 控件,若希望 DataGrid 从其数据源确定列,则将 AutoGenerateColumns 属性设置为 True,设置 DataGrid 的 ItemsSource 属性指定要在 DataGrid 中显示的数据集合。 |
| 异步调用 Web 服务 | 导入 System.Net 命名空间,使用 WithEvents 关键字定义一个 WebClient 对象,为 WebClient 创建一个 DownloadStringCompleted 事件处理程序,通过调用 WebClient 对象的 DownloadStringAsync 方法并传入 Web 服务的 Uri 异步调用 Web 服务,当 DownloadStringCompleted 事件处理程序被调用时,参数的 Result 属性包含 Web 服务的响应字符串。 |
| 解析从 Web 服务返回的 XML 数据 | 添加对 System.Linq.Xml 程序集的引用,导入 System.Xml.Linq 命名空间,导入 Web 服务返回的 XML 的命名空间,创建一个 XDocument 变量并使用 XDocument.Parse 方法将包含 XML 的字符串转换为可用于 LINQ to XML 的对象。 |
| 使用 LINQ to XML 将 XML 转换为对象集合 | 使用 LINQ 的 From 子句从 XDocument 对象中选择项目,使用 XML 后代属性指定要选择的元素,使用 Where 子句指定选择条件,使用 Select 将每个选定的元素转换为新对象,使用 With 关键字表示隐式使用新对象访问其属性,使用 Visual Basic 2008 的新 XML 属性语法访问选定元素的子元素并使用 Value 属性获取子元素的值。 |
| 使用 ListBox 控件显示对象集合 | 设置 ListBox 的 ItemsSource 属性指定要在 ListBox 中显示的数据集合。 |
| 更改 ListBox 控件的 ItemTemplate | 使用 ListBox.ItemTemplate 元素替换 ListBox 的默认 ItemTemplate,在 ListBox.ItemTemplate 元素中放置一个 DataTemplate 元素,以便将数据源(如集合)中的数据绑定到 ListBox 的项目,在 DataTemplate 元素中定义一个布局容器,其中包含表示渲染项目的新方式的嵌套元素,使用 Binding 标记扩展选择应绑定到控件的对象属性。 |
| 更改 ListBox 控件的 ItemsPanel | 使用 ListBox.ItemsPanel 元素替换 ListBox 的默认 ItemsPanel,在 ListBox.ItemsPanel 元素中嵌套一个 ItemsPanelTemplate 元素指定 ListBox 元素的方向,在 ItemsPanelTemplate 元素中定义排列 ListBox 项目的新方式。 |
| 向 Silverlight 应用程序添加自定义控件 | 在解决方案资源管理器中右键单击项目名称,选择“Add”>“New Item…”,选择 Silverlight 用户控件模板并命名文件,像为应用程序的主 GUI 一样定义控件和布局。 |
| 使用数据绑定与自定义控件 | 设置自定义控件的 DataContext 属性为提供绑定数据的对象,使用 Binding 标记扩展选择要绑定到自定义控件中控件的属性。 |
5. 关键术语
| 术语 | 定义 |
|---|---|
| assembly | 用于打包编译后的 .NET 代码以便重用的机制。 |
| AutoGenerateColumns 属性(DataGrid) | 当设置为 True 时,表示 DataGrid 应从其数据源确定列。 |
| App.xaml | 声明 Silverlight 应用程序共享资源(如可应用于各种 GUI 元素的样式)的 XAML 文件。 |
| App.xaml.vb | 定义应用程序级事件处理程序(如未处理异常的事件处理程序)的代码隐藏文件。 |
| Binding 标记扩展 | 将对象的属性绑定到控件的属性。 |
| Border 元素 | 用于在任何 Silverlight 控件周围放置边框。 |
| Button 元素 | 在 Silverlight GUI 中显示一个按钮。 |
| Button 的 Click 事件 | 当用户按下按钮时引发。 |
| 使用 Web 服务 | 调用 Web 服务并处理其结果的过程。 |
| Button 的 Content 属性 | 指定按钮上的文本。 |
| Border 的 CornerRadius 属性 | 指定边框角的圆角程度。 |
| Silverlight 控件的 DataContext 属性 | 指定控件可通过 Binding 标记扩展获取数据的对象。 |
| DataGrid 控件 | 以行和列的形式显示数据,可通过其 ItemsSource 属性将对象集合绑定到该控件。 |
| WebClient 类的 DownloadStringAsync 方法 | 异步调用 Web 服务,使应用程序可以继续执行。 |
| WebClient 类的 DownloadStringCompleted 事件 | 当 Web 服务响应异步调用时引发。 |
| DownloadStringCompletedEventArgs 类的 Error 属性 | 指定在 Web 服务调用期间发生的错误(如果有)。 |
| Rectangle 元素的 Fill 属性 | 指定矩形的填充颜色。 |
| Silverlight 控件的 FontSize 属性 | 指定控件使用的字体的像素大小。 |
| Silverlight 控件的 Grid.Column 属性 | 指定控件应放置在封闭 Grid 布局容器中的列。 |
| Grid.ColumnDefinitions 元素 | Grid 布局容器的嵌套元素,包含一组定义 Grid 列及其特性的 ColumnDefinition 元素。 |
| Silverlight 控件的 Grid.ColSpan 属性 | 指定控件在其封闭 Grid 布局容器中应占据的列数。 |
| Silverlight 控件的 Grid.Row 属性 | 指定控件应放置在封闭 Grid 布局容器中的行。 |
| Grid.RowDefinitions 元素 | Grid 布局容器的嵌套元素,包含一组定义 Grid 行及其特性的 RowDefinition 元素。 |
| Silverlight 控件的 Grid.RowSpan 属性 | 指定控件在其封闭 Grid 布局容器中应占据的行数。 |
| Image 控件 | 在 Silverlight GUI 中加载并显示图像。 |
| ListBox 的 ItemsPanel | 见 ListBox.ItemsPanel 元素。 |
| ItemsPanelTemplate 元素 | 用于重新定义 ListBox 的 ItemsPanel,以更改 ListBox 项目的排列方式。 |
| ListBox 的 ItemTemplate | 见 ListBox.ItemTemplate 元素。 |
| LINQ to XML | 支持操作 XML 数据的 LINQ 功能。 |
| ListBox 控件 | 在 Silverlight GUI 中显示项目列表,用户可以从中选择。 |
| ListBox.ItemsPanel 元素 | 定义 ListBox 中的项目在 GUI 中的排列方式(如垂直、水平等)。 |
| ListBox.ItemTemplate 元素 | 定义每个 ListBox 项目的外观和感觉,默认的 ItemTemplate 显示每个项目的字符串表示形式。 |
| Silverlight 控件的 Margin 属性 | 指定控件边缘周围的空间量。 |
| Rectangle 元素的 Opacity 属性 | 指定矩形的透明度,值范围从 0 到 1,0 表示完全透明,1 表示完全不透明。 |
| StackPanel 布局容器的 Orientation 属性 | 确定 StackPanel 是否垂直(默认)或水平排列其子元素。 |
| Page.xaml | 定义 Silverlight 应用程序 GUI 的 XAML 文件。 |
| Page.xaml.vb | 声明 GUI 事件处理程序(以及 Silverlight 应用程序所需的其他方法)的代码隐藏文件。 |
| Rectangle 元素 | 在 Silverlight GUI 中显示一个矩形。 |
| Representational State Transfer (REST) | 一种调用 Web 服务的方式,其中每个操作由唯一的 URL 标识。 |
| DownloadStringCompletedEventArgs 类的 Result 属性 | 表示被调用 Web 服务返回结果的字符串。 |
| Rich Internet Applications (RIAs) | 提供桌面应用程序的响应性和丰富 GUI 功能的 Web 应用程序。 |
| RowDefinition 元素 | 嵌套在 Grid.RowDefinitions 元素中,用于指定 Grid 布局容器中行的特性。 |
| Grid 布局容器的 ShowGridLines 属性 | 显示网格线,以便在设计和构建 GUI 时查看网格布局。 |
| Silverlight | Microsoft 用于富互联网应用程序(RIAs)的平台。 |
| Silverlight 应用程序项目模板 | 用于构建 Silverlight 应用程序的 Visual Studio 2008 项目模板,使用此模板需要安装 Visual Studio 2008 的 Silverlight 工具。 |
| Image 的 Source 属性 | 指定要在控件中显示的图像的 URL。 |
| TextBlock 的 Text 属性 | 指定 TextBlock 中的文本。 |
| TextBlock 元素 | 在 Silverlight GUI 中显示文本。 |
| TextBox 的 TextChanged 事件 | 当用户更改 TextBox 中的文本时引发。 |
| UserControl | Silverlight 应用程序中的主要元素,包含 GUI 中的所有其他元素。 |
| Silverlight 控件的 Visibility 属性 | 指定控件在 GUI 中是可见还是折叠(不可见)。 |
| Web 应用程序项目 | 可用于在 Web 浏览器中测试 Silverlight 应用程序的项目,创建新的 Silverlight 应用程序时可以为你创建一个这样的项目。 |
| Web 服务 | 存储在一台计算机上的软件组件,可通过网络由另一台计算机上的应用程序(或其他软件组件)通过方法调用进行访问。 |
| WebClient 类 | 可用于调用 Web 服务的对象类。 |
| WithEvents 关键字 | 用于声明可以生成事件的对象,使你能够为这样的对象创建事件处理程序。 |
| .xap 文件 | 编译后的 Silverlight 应用程序的文件扩展名,由 IDE 打包成包含应用程序及其支持资源(如图像或应用程序使用的其他文件)的文件。 |
| Silverlight 控件的 x:Name 属性 | 用于指定控件的名称,以便从 Visual Basic 以编程方式访问它。 |
| XDocument 类 | 使你能够以编程方式处理 XML 数据的类。 |
| XDocument.Parse 方法 | 将包含 XML 的字符串转换为可与 LINQ to XML 一起使用的对象的方法。 |
| XML 后代属性 | 新的 Visual Basic 2008 语法,用于指定从 XML 文档中选择要在 LINQ to XML 表达式中处理的元素。 |
| XML 轴属性 | 用于直接从 Visual Basic 代码访问 XML 元素的新 Visual Basic 2008 语法。 |
6. 选择题
6.1 问题及选项
| 问题 | 选项 |
|---|---|
| DataGrid 的哪个属性指定要在控件中显示的对象集合? |
a) DataSource
b) DataContext c) ItemsSource d) 以上都不是 |
| 哪个类的对象可用于调用 Web 服务? |
a) WebClient
b) WebService c) CallService d) 以上都不是 |
| ListBox 控件的哪个属性可用于自定义 ListBox 项目的外观和感觉? |
a) ItemsPanel
b) ItemTemplate c) ItemsSource d) 以上都不是 |
| ListBox 控件的哪个属性指定 ListBox 项目的排列方式? |
a) ItemsPanel
b) ItemTemplate c) ItemsSource d) 以上都不是 |
| 在应用程序中使用 LINQ to XML 需要哪个命名空间? |
a) System.Linq
b) System.Xml c) System.Xml.Linq d) 以上都不是 |
| 哪个元素定义 Grid 布局容器中的行? |
a) Grid.Rows
b) Grid.RowDefinitions c) GridRowDefinitions d) 以上都不是 |
| 以下哪些是 Silverlight 中的布局容器? |
a) Canvas
b) StackPanel c) Grid d) 以上都是 |
| 哪个布局容器允许绝对定位其子元素? |
a) Canvas
b) StackPanel c) Grid d) 以上都是 |
| XML 元素 Employee 的 Visual Basic XML 属性语法是什么? |
a) Employee
b) c) “Employee” d) 以上都不是 |
| XDocument 方法哪个将包含 XML 的字符串转换为可与 LINQ to XML 一起使用的对象? |
a) Convert
b) CreateXML c) Parse d) 以上都不是 |
6.2 答案
| 问题编号 | 答案 |
|---|---|
| 32.1 | c |
| 32.2 | a |
| 32.3 | b |
| 32.4 | a |
| 32.5 | c |
| 32.6 | b |
| 32.7 | d |
| 32.8 | a |
| 32.9 | a |
| 32.10 | c |
7. 练习
7.1 增强型天气查看器应用程序
7.1.1 需求
修改天气查看器应用程序,以显示用户输入的邮政编码对应的城市和州的名称。这些信息由 Web 服务返回的 XML 中名为 PlaceName 和 StateCode 的元素指定。
7.1.2 操作步骤
- 复制模板到工作目录 :将目录 C:\Examples\Tutorial32\Exercises\WeatherViewer_Enhanced 复制到你的 C:\SimplyVB2008 目录。
- 打开应用程序的模板文件 :双击 WeatherViewer 目录中的 WeatherViewer.sln 打开应用程序。
- 添加新的 RowDefinition :在 Page.xaml 的第 8 和 9 行之间添加一个新的 RowDefinition,并将其 Height 属性设置为 35 像素。注意,需要将 WeatherDetailsView 的 RowSpan 从 2 更新为 3。
- 更改 ListBox 在 Grid 中的行 :在 Page.xaml 的第 41 行,将 ListBox 的 Grid.Row 属性从 1 更改为 2,使其出现在主 Grid 的底部行。
- 在主 Grid 的中间行添加水平 StackPanel :在第 41 行的 ListBox 之前插入一个 StackPanel,将其 Orientation 属性设置为 Horizontal,Grid.Row 属性设置为 1。将此控件的 x:Name 属性设置为 cityStateStackPanel。
- 向 StackPanel 添加 TextBlocks :向 StackPanel 添加四个 TextBlocks。将第一个 TextBlock 的 Text 属性设置为“City:”,第三个 TextBlock 的 Text 属性设置为“State:”,用作其他两个 TextBlocks 的标签。将所有四个 TextBlocks 的 Margin 属性设置为 5。
- 向项目添加 CityState 类 :在解决方案资源管理器中右键单击 WeatherViewer 项目,选择“Add”>“Existing Item…”。导航到 C:\Examples\Tutorial32\Exercises\,双击 CityState.vb 将文件添加到项目中。此类包含 String 类型的 City 和 State 属性。
- 创建包含城市和州信息的 CityState 类对象 :在 Page.xaml.vb 文件的 DisplayWeatherForecast 方法的第 52 行之后插入以下代码:
' new object containing City and State properties
Dim cityStateObject = New CityState With {
.City = weatherXML...<PlaceName>.Value,
.State = weatherXML...<StateCode>.Value
} ' end creation of new object
- 设置 cityStateStackPanel 的 DataContext :在步骤 8 插入的代码之后立即插入以下代码,使 cityStateStackPanel 能够使用 cityStateObject 中的数据:
' bind object to cityStateStackPanel
cityStateStackPanel.DataContext = cityStateObject
- 将城市和州信息绑定到 cityStateStackPanel 中的 TextBlocks :在步骤 6 中的第二个和第四个 TextBlocks 中,使用 Binding 标记扩展设置 Text 属性。第二个 TextBlock 的 Text 属性应设置为 City 属性,第四个 TextBlock 的 Text 属性应设置为 State 属性。
- 运行应用程序 :选择“Debug”>“Start Debugging”运行应用程序。输入一个邮政编码,确认城市和州信息正确显示。
- 关闭应用程序 :点击浏览器的关闭框关闭正在运行的应用程序。
- 关闭 IDE :点击 IDE 的关闭框关闭 IDE。
7.2 长度/距离转换器编程挑战
7.2.1 需求
使用网站 www.webservicex.net 提供的长度/距离转换器 Web 服务,结合所学技术创建一个 Silverlight 长度/距离转换器。用户应能够在 TextBox 中输入一个数字,然后从 ListBox 中选择两个测量单位,并点击一个按钮调用 Web 服务。
7.2.2 操作步骤
- 可以使用以下形式的 URL 调用 Web 服务:
http://www.webservicex.net/length.asmx/ChangeLengthUnit?LengthValue=100&fromLengthUnit=Inches&toLengthUnit=Centimeters
- Web 服务返回的 XML 如下:
<?xml version="1.0" encoding="utf-8" ?>
<double xmlns="http://www.webserviceX.NET/">254</double>
- Web 服务方法 ChangeLengthUnit 需要三个 String 类型的参数:LengthValue、fromLengthUnit 和 toLengthUnit。可以在以下网页的 WSDL Schema 部分找到 fromLengthUnit 和 toLengthUnit 参数的完整值列表:
http://www.webservicex.net/WCF/ServiceDetails.aspx?SID=71
-
实现步骤如下:
- 创建一个 TextBox 供用户输入数字。
- 创建两个 ListBox,将每个 ListBox 的 ItemsSource 属性绑定到包含完整测量名称的字符串数组。
- 创建一个 Button,当用户点击时调用 Web 服务。
8. 流程图
graph TD;
A[开始] --> B[创建 Silverlight 应用程序项目];
B --> C[设计 GUI 布局];
C --> D[添加用户控件];
D --> E[处理 Web 服务调用];
E --> F[解析返回的 XML 数据];
F --> G[显示天气信息];
G --> H[添加事件处理程序];
H --> I[增强应用功能];
I --> J[运行和测试应用程序];
J --> K[结束];
通过以上步骤和代码示例,你可以开发一个完整的天气查看器应用程序,并根据需求进行扩展和优化。同时,掌握了 Silverlight 开发中的多种关键技术,如布局容器的使用、Web 服务调用、XML 解析和数据绑定等。在实际开发中,可以根据具体需求进一步调整和完善应用程序。
8. 部分代码详细解释
8.1 Page.xaml.vb 中的
DisplayWeatherForecast
方法
Private Sub DisplayWeatherForecast(ByVal xmlData As String)
' parse the XML data for use with LINQ
Dim weatherXML As XDocument = XDocument.Parse(xmlData)
' convert XML into WeatherData objects using XML literals
Dim weatherInformation = _
From item In weatherXML...<WeatherData> _
Where Not item.IsEmpty _
Select New WeatherData With _
{ _
.DayOfWeek = item.<Day>.Value, _
.WeatherImage = item.<WeatherImage>.Value, _
.MaxTemperatureF = Convert.ToInt32( _
item.<MaxTemperatureF>.Value), _
.MinTemperatureF = Convert.ToInt32( _
item.<MinTemperatureF>.Value), _
.MaxTemperatureC = Convert.ToInt32( _
item.<MaxTemperatureC>.Value), _
.MinTemperatureC = Convert.ToInt32( _
item.<MinTemperatureC>.Value) _
} ' end LINQ to XML that creates WeatherData objects
' bind forecastList.ItemsSource to the weatherInformation
forecastList.ItemsSource = weatherInformation
End Sub ' DisplayWeatherForecast
-
XML 解析
:使用
XDocument.Parse(xmlData)将从 Web 服务获取的 XML 字符串解析为XDocument对象,以便后续使用 LINQ to XML 进行处理。 - LINQ to XML 查询 :
-
From item In weatherXML...<WeatherData>:从weatherXML文档中选择所有WeatherData元素。 -
Where Not item.IsEmpty:过滤掉空的WeatherData元素。 -
Select New WeatherData With {...}:将每个选中的WeatherData元素转换为WeatherData对象,使用 XML 属性语法访问子元素的值,并将其赋值给WeatherData对象的属性。 -
数据绑定
:将
forecastList的ItemsSource属性设置为weatherInformation,这样ListBox就会显示weatherInformation集合中的数据。
8.2 WeatherDetailsView.xaml.vb 中的
closeButton_Click
方法
Private Sub closeButton_Click(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles closeButton.Click
Me.Visibility = Windows.Visibility.Collapsed
End Sub ' closeButton_Click
-
当用户点击关闭按钮时,该事件处理程序将
WeatherDetailsView控件的Visibility属性设置为Collapsed,从而隐藏该控件。
9. 可能遇到的问题及解决方案
| 问题 | 解决方案 |
|---|---|
| Web 服务调用失败 | 检查网络连接是否正常,确认 Web 服务的 URL 是否正确,查看 Web 服务是否可用。 |
| XML 解析错误 | 确保从 Web 服务返回的 XML 格式正确,检查 XML 命名空间是否正确导入。 |
| 数据绑定不显示 |
检查
DataContext
属性是否正确设置,
Binding
标记扩展中的属性名是否与数据源的属性名一致。
|
| 控件布局不符合预期 |
检查 Grid 的行和列定义是否正确,控件的
Grid.Row
、
Grid.Column
、
Grid.RowSpan
和
Grid.ColSpan
属性是否设置正确。
|
10. 总结
10.1 主要技术点
- Silverlight 开发 :使用 XAML 标记语言构建用户界面,结合 Visual Basic 代码实现功能逻辑。
-
Web 服务调用
:使用
WebClient类异步调用 Web 服务,处理DownloadStringCompleted事件获取服务响应。 - LINQ to XML :使用 LINQ to XML 对从 Web 服务返回的 XML 数据进行解析和转换。
-
数据绑定
:通过
DataContext属性和Binding标记扩展将数据与 GUI 控件关联起来。 -
布局容器
:使用
Grid和StackPanel等布局容器来控制控件的布局。
10.2 开发流程总结
graph LR;
A[创建项目] --> B[设计界面];
B --> C[处理 Web 服务];
C --> D[解析数据];
D --> E[绑定数据到控件];
E --> F[添加事件处理];
F --> G[测试和优化];
10.3 未来扩展方向
- 增加更多天气信息 :如风力、湿度等,从 Web 服务返回的 XML 中提取相应数据并显示。
- 用户交互优化 :例如添加动画效果、提示信息等,提升用户体验。
- 多语言支持 :通过资源文件实现不同语言的显示,满足不同用户的需求。
通过以上的学习和实践,你可以掌握开发一个完整的天气查看器应用程序的技能,并且可以根据自己的需求进行进一步的扩展和优化。在实际开发过程中,不断积累经验,提高解决问题的能力,以应对各种复杂的开发场景。
超级会员免费看
983

被折叠的 条评论
为什么被折叠?



