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

Xamarin.Forms CollectionView加点击手势改背景色多item异常变色问题

问题原因及解决方案

问题原因

这个问题是Xamarin.Forms中CollectionView的UI虚拟化(视图复用)机制导致的:

  • CollectionView不会为所有数据项单独创建对应的视图容器,只会创建足以填满可视区域的少量视图,当你滚动列表时,会把滚出屏幕的视图回收,重新绑定新的数据后复用给新滚入屏幕的项。
  • 你直接在点击事件里修改Frame的背景色,相当于修改了可复用视图的属性,这个视图被复用到其他数据项时,修改后的背景色不会自动重置,就会出现未点击的项也跟着变色的问题。

解决方案

不要直接修改视图的属性,把选中状态下沉到绑定的数据源模型中,通过数据绑定自动控制背景色,步骤如下:

  1. 给你的数据模型添加IsSelected属性,并且实现INotifyPropertyChanged接口:
public class YourItemModel : INotifyPropertyChanged
{
    private bool _isSelected;
    public bool IsSelected
    {
        get => _isSelected;
        set
        {
            _isSelected = value;
            OnPropertyChanged();
        }
    }

    private string _title;
    public string Title
    {
        get => _title;
        set
        {
            _title = value;
            OnPropertyChanged();
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}
  1. 实现bool到颜色的值转换器:
public class SelectedToColorConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is bool isSelected && isSelected)
        {
            return Color.FromHex("#60CED3");
        }
        return Color.FromHex("#2C2E31");
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
  1. 修改自定义ContentView的XAML,添加转换器引用,绑定Frame的背景色:
    首先在ContentView的头部添加转换器资源:
<ContentView.Resources>
    <local:SelectedToColorConverter x:Key="SelectedToColor"/>
</ContentView.Resources>

然后修改Frame的属性:

<Frame BackgroundColor="{Binding IsSelected, Converter={StaticResource SelectedToColor}}" 
       IsClippedToBounds="False" 
       Padding="15,15,15,15" 
       CornerRadius="12">
  1. 修改点击事件逻辑,只修改模型的IsSelected属性,如果需要单选效果,还要遍历数据源把其他项的IsSelected设为false:
void TapGestureRecognizer_Tapped(System.Object sender, System.EventArgs e)
{
    var item = sender as Xamarin.Forms.Frame;
    if (item.BindingContext is YourItemModel model)
    {
        // 如果需要单选,先把所有项的选中状态取消,yourCollectionViewItemsSource替换为你绑定给CollectionView的数据源
        foreach (var m in yourCollectionViewItemsSource)
        {
            m.IsSelected = false;
        }
        // 再设置当前项为选中
        model.IsSelected = true;
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 23:12:03