练习 - 将代码替换为 .NET MAUI 绑定
在本练习中,你将把一个使用事件和后台代码的应用程序转换为一个主要使用数据绑定的应用程序。 示例应用是一个天气预报应用,用于显示当天的天气。
打开初学者解决方案
从 GitHub 克隆或下载练习存储库。
注意
最好将练习内容克隆或下载到较短的文件夹路径(例如 C:\dev),以避免生成进程生成的文件超过最大路径长度。
使用 Visual Studio 或打开 Visual Studio Code 中的启动文件夹,从起始文件夹中打开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 文件。
查找包含所有
Grid控件的内部Label。<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中定义的 类型的属性。 请记住,此类型是天气服务返回的数据类型。例如,命名为
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枚举值在代码中选择的图像资源。 需要进行额外的工作才能将枚举值更改为图像资源。 在了解更多关于绑定的信息后,你将在下一个练习中解决此问题。