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

MAUI自定义IconPicker控件FontImageSource主题切换不更新问题

解决方案:自定义Picker控件FontImageSource主题切换不更新问题

问题根源

当FontImageSource的Color通过AppThemeBinding动态切换主题时,其内部属性变更不会自动触发父控件IconPicker的Source属性的OnPropertyChanged事件,导致自定义PickerHandler的MapSource方法未执行,图标无法重绘。原生Image控件内部已处理此逻辑,但自定义控件需手动实现。

修复步骤

1. 修正Source可绑定属性的定义

移除属性setter内的事件监听(MAUI绑定系统可能绕过setter直接调用SetValue),改用BindableProperty的propertyChanged回调来处理ImageSource的事件监听与解绑:

public static readonly BindableProperty SourceProperty = BindableProperty.Create(
    nameof(Source),
    typeof(ImageSource),
    typeof(IconPicker),
    defaultValue: default(ImageSource),
    propertyChanged: OnSourceChanged);

public ImageSource Source
{
    get => (ImageSource)GetValue(SourceProperty);
    set => SetValue(SourceProperty, value);
}

private static void OnSourceChanged(BindableObject bindable, object oldValue, object newValue)
{
    var iconPicker = (IconPicker)bindable;
    
    // 解绑旧值的PropertyChanged事件
    if (oldValue is INotifyPropertyChanged oldSource)
    {
        oldSource.PropertyChanged -= iconPicker.OnSourcePropertyChanged;
    }
    
    // 绑定新值的PropertyChanged事件
    if (newValue is INotifyPropertyChanged newSource)
    {
        newSource.PropertyChanged += iconPicker.OnSourcePropertyChanged;
    }
    
    // 首次设置时触发一次更新
    iconPicker.OnPropertyChanged(nameof(Source));
}

2. 处理ImageSource内部属性变更

实现监听方法,当FontImageSource的Color属性变化时,手动触发IconPicker的Source属性变更通知:

private void OnSourcePropertyChanged(object sender, PropertyChangedEventArgs e)
{
    // 仅当Color属性变化时触发Source的变更通知
    if (e.PropertyName == nameof(FontImageSource.Color))
    {
        OnPropertyChanged(nameof(Source));
    }
}

3. 清理事件监听(避免内存泄漏)

在控件卸载时,解绑ImageSource的事件监听:

protected override void OnHandlerChanged()
{
    base.OnHandlerChanged();
    
    // 当Handler被移除时,清理Source的事件监听
    if (Handler == null && Source is INotifyPropertyChanged source)
    {
        source.PropertyChanged -= OnSourcePropertyChanged;
    }
}

验证逻辑

通过上述修改,当主题切换导致FontImageSource.Color变化时,会触发OnSourcePropertyChanged方法,进而调用OnPropertyChanged(nameof(Source)),促使PickerHandler的MapSource方法执行,重新绘制图标。

补充说明

原生Image控件能正常工作,是因为其内部Handler会监听ImageSource的所有属性变更,包括FontImageSource的Color。自定义控件需要手动复刻这一逻辑,确保内部属性变更能传递到控件层级,触发UI更新。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 03:55:08