WPF DataGrid双击行取值报CS1061无Selected定义错误求助
问题根因
CS1061属于编译阶段错误,和你当前双击行填充表单的运行时逻辑无关。你观察到文本框能正常加载数据,是因为Visual Studio启动了上一次编译成功的历史程序集,并非当前带错误的代码编译通过。
该错误的触发逻辑非常明确:你的项目代码中存在对WPF DataGrid类型Selected成员的调用,但System.Windows.Controls.DataGrid原生不存在名为Selected的属性或事件,编译器无法识别该成员。
常见触发场景
- 后台其他位置手误编写了类似
dgvUsers.Selected += 事件处理方法的代码,Selected是WinFormDataGrid、部分第三方网格控件的事件,不属于WPF原生DataGrid - XAML的Style、触发器、事件Setter中误写了
<EventSetter Event="DataGrid.Selected" Handler="xxx"/>,WPF DataGrid的选中相关路由事件为SelectionChanged、SelectedCellsChanged,不存在Selected事件 - 项目同时引入了WinForm和WPF的程序集,发生类型同名冲突,编译器将WPF的
dgvUsers识别为WinForm的DataGrid类型,同时存在不匹配的成员调用 - 冗余的无效绑定触发XAML生成代码异常:你XAML中写了
SelectedItem="{Binding SelectedItem}",如果当前DataContext没有实现该属性,部分.NET Framework版本的XAML代码生成器可能产生错误的成员调用代码
排查与修复步骤
- 第一步:全局搜索整个项目的
.Selected关键词,筛选所有和dgvUsers、DataGrid相关的调用,删除所有直接访问DataGrid.Selected成员的代码。WPF DataGrid选中相关的合法成员只有:- 属性:
SelectedItem、SelectedItems、SelectedIndex - 事件:
SelectionChanged、SelectedCellsChanged
- 属性:
- 第二步:排查命名空间冲突。如果项目需要同时使用WinForm和WPF控件,在cs文件头部给WPF DataGrid定义别名,避免类型识别错误:
后续声明WPF DataGrid类型时统一使用别名指代。using WpfDataGrid = System.Windows.Controls.DataGrid; - 第三步:清理冗余绑定。如果你的后台代码没有实现带
INotifyPropertyChanged的SelectedItem视图模型属性,直接删除XAML中SelectedItem="{Binding SelectedItem}"这段代码即可,现有双击逻辑不需要该绑定支持。 - 第四步:优化现有双击事件逻辑。你当前通过
ItemContainerGenerator取行容器的写法存在冗余,且在DataGrid开启行虚拟化时会出现取到null的问题,替换为以下更稳定的实现,增加双击位置判断,避免点击表头、空白区域时误触发逻辑:// 注意:需引入命名空间 using System.Windows.Media; private void dgvUsers_MouseDoubleClick(object sender, MouseButtonEventArgs e) { if (e.OriginalSource is not DependencyObject clickSource) return; DataGridRow clickedRow = FindVisualParent<DataGridRow>(clickSource); if (clickedRow == null) return; try { if (sender is DataGrid grid && grid.SelectedItem is DataRowView dr) { txtUserID.Text = dr[0].ToString(); txtFirstName.Text = dr[1].ToString(); txtLastName.Text = dr[2].ToString(); txtEmail.Text = dr[3].ToString(); txtUserName.Text = dr[4].ToString(); txtPassword.Text = dr[5].ToString(); txtContact.Text = dr[6].ToString(); txtAddress.Text = dr[7].ToString(); cmbGender.Text = dr[8].ToString(); cmbUserType.Text = dr[9].ToString(); } } catch (Exception ex) { MessageBox.Show(ex.Message); } } // 视觉树查找辅助方法 private static T FindVisualParent<T>(DependencyObject child) where T : DependencyObject { DependencyObject parent = VisualTreeHelper.GetParent(child); if (parent == null) return null; return parent is T matchedParent ? matchedParent : FindVisualParent<T>(parent); } - 第五步:清理解决方案后重新生成。删除项目目录下的
bin、obj文件夹,再重新生成项目,即可清除历史临时生成代码的缓存错误。
内容的提问来源于stack exchange,提问作者Akaret P
相关产品推荐
相关产品推荐

