练习 - 使用动态资源来更新元素

已完成

在本练习中,使用 DynamicResource 标记扩展在资源值更改时更新 TipCalculator UI。

本练习是上一个练习的延伸。 使用现有解决方案开始执行以下步骤,或打开在上一练习中克隆的存储库的 exercise2/TipCalculator 文件夹中的 TipCalculator 项目。

找到重复的代码

该应用为 StandardTipPage 页实现了简单的“浅色”和“深色”配色方案。 接下来,检查用于更改颜色的代码。

  1. 打开 StandardTipPage.xaml.cs 文件。

  2. 找到更新 UI 颜色的两个事件处理程序。

    private Color colorNavy = Colors.Navy;
    private Color colorSilver = Colors.Silver;
    
    ...
    
    void OnLight(object sender, EventArgs e)
    {
        LayoutRoot.BackgroundColor = colorSilver;
    
        tipLabel.TextColor = colorNavy;
        billLabel.TextColor = colorNavy;
        totalLabel.TextColor = colorNavy;
        tipOutput.TextColor = colorNavy;
        totalOutput.TextColor = colorNavy;
    }
    
    void OnDark(object sender, EventArgs e)
    {
        LayoutRoot.BackgroundColor = colorNavy;
    
        tipLabel.TextColor = colorSilver;
        billLabel.TextColor = colorSilver;
        totalLabel.TextColor = colorSilver;
        tipOutput.TextColor = colorSilver;
        totalOutput.TextColor = colorSilver;
    }
    
    ...
    

    请注意代码通过何种方式单独更新每个控件的颜色,从而造成重复代码。

从代码更新资源

首先编写用于更新存储在页面资源字典中的一些资源的代码。

  1. 从 OnLight 方法中删除所有代码。

  2. 将下面显示的代码添加到 OnLight 方法中。 此代码将页面的资源字典中的 fgColor 资源设置为 colorNavy 变量中的值,并将 bgColor 资源设置为 colorSilver 变量中的值。 colorNavy 和 colorSilver 变量使用静态 Color.FromRgb 方法,这样可以轻松地将十六进制值转换为颜色。

    void OnLight(object sender, EventArgs e)
    {
        Resources["fgColor"] = colorNavy;
        Resources["bgColor"] = colorSilver;
    }
    
  3. 重复 OnDark 方法的前两个步骤,但反转颜色;将 fgColor 设置为 colorSilver,并将 bgColor 设置为 colorNavy

    void OnDark(object sender, EventArgs e)
    {
        Resources["fgColor"] = colorSilver;
        Resources["bgColor"] = colorNavy;
    }
    
  4. 运行应用。 选择“深色”和“浅色”按钮。 UI 不会发生变化。 即使代码更改了字典中的资源值,新的值也不会传播到 UI。 问题是使用 StaticResource 标记扩展在 XAML 代码中设置值。

动态更新 UI

要解决此问题,请修改 XAML,以便将更新后的资源值加载到 UI 中。

  1. 停止应用,并打开 StandardTipPage.xaml 文件。

  2. 找到从资源值分配颜色的所有位置。 不使用 StaticResource 标记扩展,而是使用 DynamicResource,如此示例所示。

    <Grid x:Name ="LayoutRoot" BackgroundColor="{DynamicResource bgColor}" Padding="10">
    ...
    <Label x:Name="billLabel"  Text="Bill"  TextColor="{DynamicResource fgColor}" ... />
    <Label x:Name="tipLabel"   Text="Tip"   TextColor="{DynamicResource fgColor}" ... />
    <Label x:Name="totalLabel" Text="Total" TextColor="{DynamicResource fgColor}" ... />
    ...
    

    注意

    请勿将 FontSize 属性从 StaticResource 更改为 DynamicResource。

  3. 运行应用。 选择“深色”和“浅色”按钮。 UI 现在会正确地进行更新。