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

在WPF DataGrid中操作Content属性为何需强制类型转换?

WPF DataGrid 选中行赋值异常问题分析与解决

核心问题原因

当你直接写 lblID.Content = id.Content 时,本质是把 DataGridCell 里的TextBlock 控件本身转移到了 Label 的 Content 中。WPF 的 UI 元素只能属于一个父容器,控件被移走后,原来的 DataGridCell 就失去了内容,所以 ID 列会显示为空。当最后一行被选中后,后续操作会因为控件已被移除而触发 NullReferenceException。

而 ((TextBlock)id.Content).Text 是读取 TextBlock 的文本内容(字符串),只是把字符串值赋值给 Label,不会移动 UI 控件,因此不会出现内容消失或空引用的问题。

更优解决方案:放弃操作 UI 控件,直接绑定选中数据

你当前通过遍历 DataGrid 单元格控件获取数据的方式繁琐且易出错,WPF 的核心是数据绑定,直接操作选中的数据对象才是正确做法:

1. 重构 SelectionChanged 事件代码

替换原 dgPatientTable_SelectionChanged 方法:

private void dgPatientTable_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    var selectedPatient = dgPatientTable.SelectedItem as dynamic;
    if (selectedPatient == null)
    {
        patientId = 0;
        // 清空编辑框
        tbNameUpdate.Text = "";
        tbPhoneUpdate.Text = "";
        tbEmailUpdate.Text = "";
        tbAddressUpdate.Text = "";
        tbPostalzipUpdate.Text = "";
        lblID.Content = "";
        return;
    }

    // 直接访问数据对象属性,无需操作UI控件
    lblID.Content = selectedPatient.ID.ToString();
    patientId = selectedPatient.ID;
    tbNameUpdate.Text = selectedPatient.name;
    tbPhoneUpdate.Text = selectedPatient.phone;
    tbEmailUpdate.Text = selectedPatient.email;
    tbAddressUpdate.Text = selectedPatient.address;
    tbPostalzipUpdate.Text = selectedPatient.postalZip;
}

2. 修复新增患者的上下文释放问题

原代码中 using (hp) 会释放类级别的 EF 上下文,导致后续查询报错,修改为:

private void btnAddPatient_Click(object sender, RoutedEventArgs e)
{
    using (var hpContext = new hospitalEntities())
    {
        patient newPatient = new patient()
        {
            name = tbName.Text,
            phone = tbPhone.Text,
            email = tbEmail.Text,
            address = tbAddress.Text,
            postalZip = tbPostalZip.Text
        };
        hpContext.patients.Add(newPatient);
        hpContext.SaveChanges();
        
        // 清空输入框
        tbName.Clear();
        tbPhone.Clear();
        tbEmail.Clear();
        tbAddress.Clear();
        tbPostalZip.Clear();
        
        InitializeTable();
    }
}

额外建议

  • 避免使用匿名类型,建议创建 PatientViewModel 类来封装查询结果,替换匿名类型,这样可以去掉 dynamic,提升代码的类型安全性。
  • WPF 中操作 UI 控件获取数据属于反模式,优先使用数据绑定(比如将编辑框直接绑定到选中的患者对象),能进一步减少代码量和异常风险。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 04:55:21