You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在IConverter中使用AppThemeBinding无法响应主题切换的问题求助

解决BoolToColorConverter主题切换不更新颜色的问题

你创建的BoolToColorConverter在应用启动时能根据主题正确显示颜色,但运行中切换主题时,颜色不会自动更新:

  • 启动时深色模式效果:
    深色模式启动效果
  • 启动时浅色模式效果:
    浅色模式启动效果
  • 主题切换后异常效果:
    主题切换后异常效果

原因是:绑定的触发条件是源属性(CheckBox的IsChecked)变化,而AppThemeBinding更新TrueColor时,并不会触发源属性的变化,因此转换器的Convert方法不会重新执行,导致颜色保持旧值。

以下是两种可行的解决方案:

方法一:改用IMultiValueConverter监听多源变化

将转换器改为实现IMultiValueConverter,同时把FalseColor也改为可绑定属性,这样绑定会监听IsChecked、TrueColor、FalseColor三个值的变化,任意一个变化都会触发颜色更新。

1. 更新转换器代码

public class BoolToColorConverter : BindableObject, IMultiValueConverter
{
    public static readonly BindableProperty TrueColorProperty =
        BindableProperty.Create(nameof(TrueColor), typeof(Color), typeof(BoolToColorConverter), null, BindingMode.OneWay);
  
    public Color TrueColor
    {
        get { return (Color)GetValue(TrueColorProperty); }
        set { SetValue(TrueColorProperty, value); }
    }
    
    public static readonly BindableProperty FalseColorProperty =
        BindableProperty.Create(nameof(FalseColor), typeof(Color), typeof(BoolToColorConverter), null, BindingMode.OneWay);

    public Color FalseColor
    {
        get { return (Color)GetValue(FalseColorProperty); }
        set { SetValue(FalseColorProperty, value); }
    }

    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        if (values.Length >= 3 && values[0] is bool isChecked)
        {
            var trueColor = values[1] as Color ?? Colors.Transparent;
            var falseColor = values[2] as Color ?? Colors.Transparent;
            return isChecked ? trueColor : falseColor;
        }
        return Colors.Transparent;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

2. 修改XAML中的绑定为MultiBinding

<ContentPage.Resources>
    <converts:BoolToColorConverter
        x:Key="ColorConverter" 
        TrueColor="{AppThemeBinding Light=DarkRed, Dark=LightSalmon}" 
        FalseColor="#888" />
</ContentPage.Resources>

<VerticalStackLayout>
    <Label
        Text="Hello, World!"
        FontSize="32"
        HorizontalOptions="Center">
        <Label.TextColor>
            <MultiBinding Converter="{StaticResource ColorConverter}">
                <Binding Source="{x:Reference Checky}" Path="IsChecked" />
                <Binding Source="{StaticResource ColorConverter}" Path="TrueColor" />
                <Binding Source="{StaticResource ColorConverter}" Path="FalseColor" />
            </MultiBinding>
        </Label.TextColor>
    </Label>

    <CheckBox x:Name="Checky" />
</VerticalStackLayout>

方法二:监听主题变化强制刷新绑定

如果不想修改为MultiBinding,可以在转换器中订阅应用主题变化事件,当主题切换时,手动触发绑定的刷新:

1. 更新转换器代码

public class BoolToColorConverter : BindableObject, IValueConverter
{
    private readonly List<BindableObject> _targets = new();

    public BoolToColorConverter()
    {
        Application.Current.RequestedThemeChanged += OnThemeChanged;
    }

    public static readonly BindableProperty TrueColorProperty =
        BindableProperty.Create(nameof(TrueColor), typeof(Color), typeof(BoolToColorConverter), null, BindingMode.OneWay);
  
    public Color TrueColor
    {
        get { return (Color)GetValue(TrueColorProperty); }
        set { SetValue(TrueColorProperty, value); }
    }
    
    public static readonly BindableProperty FalseColorProperty =
        BindableProperty.Create(nameof(FalseColor), typeof(Color), typeof(BoolToColorConverter), null, BindingMode.OneWay);

    public Color FalseColor
    {
        get { return (Color)GetValue(FalseColorProperty); }
        set { SetValue(FalseColorProperty, value); }
    }

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        // 记录绑定目标,用于后续刷新
        if (parameter is BindableObject target && !_targets.Contains(target))
        {
            _targets.Add(target);
        }

        if (value is bool b && b)
        {
            return TrueColor!;
        }

        return FalseColor!;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }

    private void OnThemeChanged(object sender, AppThemeChangedEventArgs e)
    {
        // 刷新所有绑定目标的属性
        foreach (var target in _targets)
        {
            foreach (var binding in target.GetBindableProperties())
            {
                var expression = target.GetBindingExpression(binding);
                expression?.UpdateTarget();
            }
        }
    }

    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            Application.Current.RequestedThemeChanged -= OnThemeChanged;
        }
        base.Dispose(disposing);
    }
}

2. 修改XAML绑定,传递目标参数

<Label
    Text="Hello, World!"
    TextColor="{Binding Source={x:Reference Checky}, Path=IsChecked, Converter={StaticResource ColorConverter}, ConverterParameter={x:Reference ThisLabel}}"
    FontSize="32"
    HorizontalOptions="Center" 
    x:Name="ThisLabel" />

内容的提问来源于stack exchange,提问作者PEK

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 16:06:27