练习 - 将代码替换为 .NET MAUI 绑定
在本练习中,你将使用事件和代码隐藏的应用转换为主要使用数据绑定的应用。 示例应用是一个天气预报应用,用于显示当天的天气。
下载并运行示例
若要启动本练习模块,请下载“天气示例”项目。 此项目显示来自虚假天气报告服务的天气。 代码不包含任何数据绑定。
下载“天气示例”项目并将其提取到临时文件夹。
导航到之前的文件夹并打开 WeatherClient.sln 解决方案。
生成并运行应用程序,确保它能正常运行。 在显示的屏幕上,你将看到一些空白的天气详细信息。 按“刷新”按钮,你将看到天气详细信息更新。
下面提供了将在本练习中使用的类和文件的摘要,以供参考:
文件 说明 MainPage.xaml 定义初始页的 UI 和逻辑。 XAML 文件使用标记来定义 UI。 MainPage.xaml.cs 定义初始页的 UI 和逻辑。 关联的代码隐藏文件,其中包含与 MainPage.xaml 定义的 UI 相关的代码。 Services\WeatherService.cs 此类模拟天气报告服务。 它包含一个名为 GetWeather
的方法,可返回类型WeatherData
。Models\WeatherData.cs 包含天气数据。 这是一个简单的记录类型,提供当天的温度、降水、湿度、风力和天气条件。 Models\WeatherType.cs 天气条件的枚举,晴或多云。
设置绑定上下文。
需要编辑“刷新”按钮的单击事件处理程序的代码隐藏。 代码当前可获取天气数据并直接更新控件。 而是获取天气数据,并将其设置为页面的绑定上下文。
打开 MainPage.xaml.cs 代码文件。
查看
btnRefresh_Clicked
方法。 此方法执行以下步骤:- 禁用该按钮并启用“忙碌”微调器。
- 从天气服务获取天气预报。
- 使用天气信息更新页面上的控件。
- 启用该按钮并禁用“忙碌”微调器。
删除使用数据更新控件的代码。 事件代码应类似于以下代码片段:
private async void btnRefresh_Clicked(object sender, EventArgs e) { btnRefresh.IsEnabled = false; actIsBusy.IsRunning = true; Models.WeatherData weatherData = await Services.WeatherServer.GetWeather(txtPostalCode.Text); btnRefresh.IsEnabled = true; actIsBusy.IsRunning = false; }
不将服务的
GetWeather
方法的结果分配给变量,而是将其分配给页面的BindingContext
:private async void btnRefresh_Clicked(object sender, EventArgs e) { btnRefresh.IsEnabled = false; actIsBusy.IsRunning = true; BindingContext = await Services.WeatherServer.GetWeather(txtPostalCode.Text); btnRefresh.IsEnabled = true; actIsBusy.IsRunning = false; }
运行该项目。 请注意,按“刷新”按钮和天气服务返回数据时,不会使用天气预报更新任何控件。 此问题将在下一部分得以解决。
通过 XAML 创建绑定
代码隐藏设置页面的绑定上下文后,可以将绑定添加到控件以使用上下文中的数据。
打开 MainPage.xaml 文件。
查找包含所有
Label
控件的内部Grid
。<Grid Grid.Row="2" RowDefinitions="Auto, Auto, Auto, Auto, Auto" ColumnDefinitions="Auto, Auto" Margin="0,5,0,0"> <Label Grid.Row="0" Grid.Column="0" Text="Condition" VerticalOptions="Center" /> <Image x:Name="imgCondition" Grid.Row="0" Grid.Column="1" HeightRequest="25" WidthRequest="25" Source="question.png" HorizontalOptions="Start" /> <Label Grid.Row="1" Grid.Column="0" Text="Temperature" Margin="0,0,20,0" /> <Label x:Name="lblTemperature" Grid.Row="1" Grid.Column="1" Text="0" /> <Label Grid.Row="2" Grid.Column="0" Text="Humidity" Margin="0,0,20,0" /> <Label x:Name="lblHumidity" Grid.Row="2" Grid.Column="1" Text="0" /> <Label Grid.Row="3" Grid.Column="0" Text="Precipitation" Margin="0,0,20,0" /> <Label x:Name="lblPrecipitation" Grid.Row="3" Grid.Column="1" Text="0" /> <Label Grid.Row="4" Grid.Column="0" Text="Wind" Margin="0,0,20,0" /> <Label x:Name="lblWind" Grid.Row="4" Grid.Column="1" Text="0" /> </Grid>
向每个命名的
Label
控件添加绑定。 有四个。该
Label.Text
属性的值应更改为{Binding PROPERTY_NAME}
语法,其中PROPERTY_NAME
是 Models\WeatherData.cs 中定义的Models.WeatherData
类型的属性。 请记住,此类型是天气服务返回的数据类型。例如,命名为
Label
的lblWind
(网格中的最后一个标签)应具有Text
类似于以下代码的属性:<Label x:Name="lblWind" Grid.Row="4" Grid.Column="1" Text="{Binding Wind}" />
在列出所有天气详细信息的控件的
<Grid>
中,删除所有x:Name="..."
属性。现在不需要名称,因为不会在代码隐藏中引用控件。
验证 XAML 绑定是否与以下代码片段匹配:
<Grid Grid.Row="2" RowDefinitions="Auto, Auto, Auto, Auto, Auto" ColumnDefinitions="Auto, Auto" Margin="0,5,0,0"> <Label Grid.Row="0" Grid.Column="0" Text="Condition" VerticalOptions="Center" /> <Image Grid.Row="0" Grid.Column="1" HeightRequest="25" WidthRequest="25" Source="question.png" HorizontalOptions="Start" /> <Label Grid.Row="1" Grid.Column="0" Text="Temperature" Margin="0,0,20,0" /> <Label Grid.Row="1" Grid.Column="1" Text="{Binding Temperature}" /> <Label Grid.Row="2" Grid.Column="0" Text="Humidity" Margin="0,0,20,0" /> <Label Grid.Row="2" Grid.Column="1" Text="{Binding Humidity}" /> <Label Grid.Row="3" Grid.Column="0" Text="Precipitation" Margin="0,0,20,0" /> <Label Grid.Row="3" Grid.Column="1" Text="{Binding Precipitation}" /> <Label Grid.Row="4" Grid.Column="0" Text="Wind" Margin="0,0,20,0" /> <Label Grid.Row="4" Grid.Column="1" Text="{Binding Wind}" /> </Grid>
运行应用,并按“刷新”按钮。 该应用的工作方式几乎与原始应用类似。
请注意,表示“条件”的图标不会从问号更新为太阳或云图标。 为什么图标不会更改? 因为图标是基于WeatherData.Condition
枚举值在代码中选择的图像资源。 如果不进行额外操作,枚举值不能更改为图像资源。在下一个练习中,在了解有关绑定的详细信息后,此问题将得以解决。