WPF应用Entity Framework删除按钮报错:Value cannot be null. Parameter name: entity
问题分析与解决方案
错误根源
你遇到的Value cannot be null. Parameter name: entity错误,核心原因是删除按钮的DataContext并非选中的船只对象:
当前删除按钮是独立于ListView的外部控件,它的DataContext和ListView的行数据没有关联,所以(sender as Button).DataContext as Катера会返回null,调用Remove(null)时自然触发参数为空的异常。
解决方案(两种可选)
方案1:利用ListView的SelectedItem(保留现有按钮位置)
直接通过ListView的选中项获取要删除的对象,修改后台删除逻辑:
private void DeleteBtn_Click(object sender, RoutedEventArgs e) { // 直接获取ListView的选中项 var currentBoat = ListViewBoats.SelectedItem as Катера; // 先判断是否选中了对象 if (currentBoat == null) { MessageBox.Show("请先选择要删除的船只"); return; } if (MessageBox.Show("Вы точно хотите выполнить удаление?", "Внимание!", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes) { try { DBGaneevaEntities.GetContext().Катера.Remove(currentBoat); DBGaneevaEntities.GetContext().SaveChanges(); ListViewBoats.ItemsSource = DBGaneevaEntities.GetContext().Катера.ToList(); } catch (Exception ex) { MessageBox.Show(ex.Message.ToString()); } } }
如果你的ViewModel中已经通过SelectedItem="{Binding currentBoat}"绑定了选中项,也可以直接使用ViewModel的currentBoat属性(需确保ViewModel实现了INotifyPropertyChanged):
var viewModel = DataContext as YourViewModelType; var currentBoat = viewModel?.currentBoat;
方案2:将删除按钮嵌入ListView每一行(更合理的交互)
把删除按钮放到ListView的行模板中,让每个按钮的DataContext自动绑定到当前行的船只对象:
修改XAML的ListView部分:
<ListView SelectedItem="{Binding currentBoat}" ItemsSource="{Binding Boats}" Name="ListViewBoats" HorizontalAlignment="Center" Margin="0,50,0,125"> <ListView.View> <GridView> <GridViewColumn DisplayMemberBinding="{Binding Path=Код_катера}" Header="Код катера" Width="100" /> <GridViewColumn DisplayMemberBinding="{Binding Path=Название}" Header="Название" Width="100"/> <GridViewColumn DisplayMemberBinding="{Binding Path=Тип}" Header="Тип" Width="150"/> <GridViewColumn DisplayMemberBinding="{Binding Path=Водоизмещение}" Header="Водоизмещение" Width="150"/> <GridViewColumn DisplayMemberBinding="{Binding Path=Дата_постройки, StringFormat='yyyy-MM-dd'}" Header="Дата постройки" Width="150"/> <!-- 添加操作列,每行对应一个删除按钮 --> <GridViewColumn Header="操作" Width="100"> <GridViewColumn.CellTemplate> <DataTemplate> <Button Content="Удалить" Click="DeleteBtn_Click"/> </DataTemplate> </GridViewColumn.CellTemplate> </GridViewColumn> </GridView> </ListView.View> </ListView>
此时你原来的后台删除代码可以直接正常工作,因为按钮的DataContext就是当前行的Катера对象。
额外优化建议
- 使用
ObservableCollection<Катера>作为ListView的ItemsSource,删除后直接从集合中移除对象,无需重新调用ToList()赋值,UI会自动更新:public ObservableCollection<Катера> Boats { get; set; } = new ObservableCollection<Катера>(); // 删除时 Boats.Remove(currentBoat); - 始终在删除前判断对象是否为空,避免无意义的异常触发。
内容的提问来源于stack exchange,提问作者yuliyagane
相关产品推荐
相关产品推荐

