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

从ObservableCollection移除项时触发InvalidCastException问题排查

问题:移除ObservableCollection项时触发InvalidCastException

我有一个包含ListView、Button和ObservableCollection的Prism视图。当从集合中移除项时,在Remove()调用处触发了InvalidCastException。有趣的是,触发异常后检查ObservableCollection的内容,发现该项实际上已被移除。


View.xaml代码

<ListView Name="lvSomeEntities" SelectionMode="Single" ItemsSource="{Binding SomeEntityList}">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="SelectionChanged">
            <prism:InvokeCommandAction Command="{Binding LvSelectionChangedCommand}" CommandParameter="{Binding ElementName=lvSomeEntities, Path=SelectedItem}" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
</ListView>

<Button Name="button" Content="Delete SomeEntity" Command="{Binding DeleteSomeEntityCommand}" CommandParameter="{Binding ElementName=lvSomeEntities, Path=SelectedItem}"/>

ViewModel.cs代码

public DelegateCommand<SomeEntity> DeleteSomeEntityCommand { get; private set; }

private ObservableCollection<SomeEntity> _someEntityList = new ObservableCollection<SomeEntity>();
public ObservableCollection<SomeEntity> SomeEntityList
{
    get { return _someEntityList; }
    set { SetProperty(ref _someEntityList, value); }
}

public ViewModel()
{
    DeleteSomeEntityCommand = new DelegateCommand<SomeEntity>(DeleteSomeEntity, DeleteSomeEntityEnabled);
}

private void DeleteSomeEntity(SomeEntity someEntity)
{
    SomeEntityList.Remove(someEntity);//此处触发InvalidCastException
}

private bool DeleteSomeEntityEnabled(SomeEntity someEntity)
{
    return someEntity != null;
}

SomeEntity.cs代码

public class SomeEntity
{
    public SomeEntity(int id, string name)
    {
        Id = id;
        Name = name;
    }

    public int Id { get; set; }
    public string Name { get; set; }

    public override string ToString()
    {
        return Id + " " + Name;
    }
}

异常信息

System.InvalidCastException: 'Unable to cast object of type 'System.Windows.Controls.SelectionChangedEventArgs' to type 'SomeEntity'.'


问题原因

异常的根源不在DeleteSomeEntity方法里的Remove调用,而是你的LvSelectionChangedCommand没有正确处理参数类型。

你在XAML里给SelectionChanged事件的InvokeCommandAction绑定了LvSelectionChangedCommand,但默认情况下,InvokeCommandAction会把事件参数(也就是SelectionChangedEventArgs)传递给命令。如果你的LvSelectionChangedCommand是声明为DelegateCommand<SomeEntity>类型,就会在尝试把SelectionChangedEventArgs强转为SomeEntity时抛出这个异常。

之所以看起来像是Remove调用触发的异常,是因为调试器的调用栈可能把异常指向了最近的用户代码,但实际异常是在选择变更事件触发时抛出的,只是延迟到UI更新阶段才被捕获。

解决方法

有两种修复方式:

  • 修正LvSelectionChangedCommand的参数传递逻辑:如果只需要传递选中项而非事件参数,在InvokeCommandAction里明确添加PassEventArgsToCommand="False",这样就会使用你绑定的SelectedItem作为命令参数:
    <i:EventTrigger EventName="SelectionChanged">
        <prism:InvokeCommandAction Command="{Binding LvSelectionChangedCommand}" 
                                   CommandParameter="{Binding ElementName=lvSomeEntities, Path=SelectedItem}"
                                   PassEventArgsToCommand="False"/>
    </i:EventTrigger>
    
  • 调整命令参数类型:如果需要处理事件参数,将LvSelectionChangedCommand声明为DelegateCommand<SelectionChangedEventArgs>类型。
  • 移除不必要的事件触发器:如果不需要通过命令处理选择变更事件,直接删除对应的i:Interaction.Triggers节点即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 09:40:36