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

MAUI自定义ViewCellRenderer/Handler失效问题求助

问题分析与解决方案

首先明确:你继承的ViewCellRenderer属于MAUI的兼容性渲染器,是从Xamarin.Forms遗留的机制,和现代MAUI Handler的PropertyMapper体系不兼容——这就是你定义的映射方法完全不触发的核心原因,基类也没有接收映射的构造函数重载,所以你尝试的base(CustomViewCellMapper)写法从一开始就走不通。

再看OnPropertyChanged没触发的问题,你的代码存在几个关键问题:

  • 使用静态变量selected和selectedColor,多个单元格会共享这些值,导致状态混乱
  • 硬编码属性名"IsSelected",一旦属性名重构就会失效,应该用nameof
  • 监听PropertyChanged的逻辑冗余,ViewCellRenderer本身已提供OnElementPropertyChanged虚方法可重写

修复后的完整代码

using System.ComponentModel;
using Microsoft.Maui.Controls.Compatibility.Platform.Android;
using Microsoft.Maui.Controls.Handlers.Compatibility;
using Microsoft.Maui.Graphics;
using Microsoft.Maui.Platform;
using NGT.Views.Customised.Controls;
using ViewCellRenderer = Microsoft.Maui.Controls.Handlers.Compatibility.ViewCellRenderer;
using global::Android.Graphics;
using Color = Android.Graphics.Color;

namespace NGT.CustomHandlers;

public class CustomViewCellHandler : ViewCellRenderer
{
    // 改为实例变量,每个单元格独立维护状态
    private bool _isSelected;
    private Color _selectedBackgroundColor;
    private CustomViewCell _customViewCell;

    protected override void ConnectHandler(Android.Views.View platformView)
    {
        base.ConnectHandler(platformView);
        _customViewCell = VirtualView as CustomViewCell;
        
        // 初始化初始值
        if (_customViewCell != null)
        {
            _selectedBackgroundColor = _customViewCell.SelectedBackgroundColor.ToAndroid();
            _isSelected = _customViewCell.IsSelected;
            UpdateCellBackgroundColor();
        }
    }

    protected override void DisconnectHandler(Android.Views.View platformView)
    {
        _customViewCell = null;
        base.DisconnectHandler(platformView);
    }

    protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs args)
    {
        base.OnElementPropertyChanged(sender, args);
        
        if (_customViewCell == null) return;

        // 处理选中状态变化
        if (args.PropertyName == nameof(CustomViewCell.IsSelected))
        {
            _isSelected = _customViewCell.IsSelected;
            UpdateCellBackgroundColor();
        }
        // 处理选中背景色变化
        else if (args.PropertyName == nameof(CustomViewCell.SelectedBackgroundColor))
        {
            _selectedBackgroundColor = _customViewCell.SelectedBackgroundColor.ToAndroid();
            // 如果当前是选中状态,立即更新颜色
            if (_isSelected)
            {
                UpdateCellBackgroundColor();
            }
        }
    }

    // 抽离更新逻辑,避免重复代码
    private void UpdateCellBackgroundColor()
    {
        if (PlatformView == null) return;
        PlatformView.SetBackgroundColor(_isSelected ? _selectedBackgroundColor : Color.Transparent);
    }
}

额外注意事项

  1. 确保你的CustomViewCell类中,IsSelected和SelectedBackgroundColor属性正确触发PropertyChanged事件:
public class CustomViewCell : ViewCell
{
    public static readonly BindableProperty SelectedBackgroundColorProperty =
        BindableProperty.Create(nameof(SelectedBackgroundColor), typeof(Color), typeof(CustomViewCell), Colors.Transparent);

    public static readonly BindableProperty IsSelectedProperty =
        BindableProperty.Create(nameof(IsSelected), typeof(bool), typeof(CustomViewCell), false);

    public Color SelectedBackgroundColor
    {
        get => (Color)GetValue(SelectedBackgroundColorProperty);
        set => SetValue(SelectedBackgroundColorProperty, value);
    }

    public bool IsSelected
    {
        get => (bool)GetValue(IsSelectedProperty);
        set => SetValue(IsSelectedProperty, value);
    }
}
  1. 在MAUIProgram.cs中注册自定义渲染器:
builder.ConfigureMauiHandlers(handlers =>
{
#if ANDROID
    handlers.AddHandler(typeof(CustomViewCell), typeof(CustomViewCellHandler));
#endif
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 20:14:54