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

.NET MAUI:CollectionView列表项无法禁用的问题求助

.NET MAUI CollectionView 无法禁用项选中的问题解决

CollectionView的项选择逻辑由控件自身独立处理,你在ItemTemplate里给ContentView设置IsEnabled="{Binding IsAvailable}",仅会禁用Item内部控件的交互(比如Label的点击响应),但无法阻止CollectionView本身触发选中操作——点击项的任何区域,控件依然会将该项标记为选中状态。

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

方法一:通过SelectionChanged事件拦截无效选择

在XAML中为CollectionView添加SelectionChanged事件:

<CollectionView 
    Margin="5,5,5,15"
    ItemSizingStrategy="MeasureAllItems"
    ItemsSource="{Binding Times}"
    SelectedItem="{Binding SelectedTime, Mode=TwoWay}"
    SelectionMode="Single"
    SelectionChanged="CollectionView_SelectionChanged">
    <!-- 原有布局代码保持不变 -->
</CollectionView>

在后台代码中实现事件处理逻辑,校验选中项的IsAvailable属性,若不可用则取消选择:

private void CollectionView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if (e.CurrentSelection.FirstOrDefault() is TimeItem selectedItem && !selectedItem.IsAvailable)
    {
        // 取消选中,恢复之前的选中项(如果存在)
        ((CollectionView)sender).SelectedItem = e.PreviousSelection.FirstOrDefault();
    }
}

注:请将TimeItem替换为你实际的数据模型类名。

方法二:在ViewModel的SelectedTime属性中处理

若使用MVVM模式,可直接在SelectedTime的setter中验证选中项有效性:

private TimeItem _selectedTime;
public TimeItem SelectedTime
{
    get => _selectedTime;
    set
    {
        // 仅当项可用时更新选中状态
        if (value != null && value.IsAvailable)
        {
            _selectedTime = value;
            OnPropertyChanged();
        }
        else
        {
            // 选中不可用项时,重置为原有值(或null)
            OnPropertyChanged(nameof(SelectedTime));
        }
    }
}

确保你的ViewModel已实现INotifyPropertyChanged接口。

方法三:使用自定义Behavior封装复用逻辑

创建一个Behavior附加到CollectionView,自动拦截无效项的选中操作,方便跨页面复用:

public class DisableUnavailableItemsBehavior : Behavior<CollectionView>
{
    protected override void OnAttachedTo(CollectionView collectionView)
    {
        base.OnAttachedTo(collectionView);
        collectionView.SelectionChanged += OnSelectionChanged;
    }

    protected override void OnDetachingFrom(CollectionView collectionView)
    {
        collectionView.SelectionChanged -= OnSelectionChanged;
        base.OnDetachingFrom(collectionView);
    }

    private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        if (sender is not CollectionView cv) return;
        var selectedItem = e.CurrentSelection.FirstOrDefault() as IHaveIsAvailable;
        if (selectedItem != null && !selectedItem.IsAvailable)
        {
            cv.SelectedItem = e.PreviousSelection.FirstOrDefault();
        }
    }
}

// 定义统一接口,规范IsAvailable属性的访问
public interface IHaveIsAvailable
{
    bool IsAvailable { get; }
}

让你的数据模型实现IHaveIsAvailable接口,然后在XAML中附加该Behavior:

<CollectionView>
    <CollectionView.Behaviors>
        <local:DisableUnavailableItemsBehavior />
    </CollectionView.Behaviors>
    <!-- 原有布局代码保持不变 -->
</CollectionView>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 00:06:16