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

LINQ填充DataGrid后,无法提取SelectedItem数据填充TextBox问题

嘿,这个问题我熟!你遇到的InvalidCastException根本原因很明确——你填充DataGrid的是LINQ返回的匿名类型对象,而不是Cards实体类,所以强行转成bdCustomer.Cards肯定会失败。毕竟匿名类型是编译器自动生成的临时类型,和你定义的Cards完全是两回事。

下面给你三种可行的解决方法,按推荐程度排序:

1. 推荐:创建强类型DTO(数据传输对象)

这是最规范、最安全的做法,适合正式项目使用。

首先定义一个和你LINQ查询结果结构匹配的DTO类:

// 可以放在项目的Models或者Dtos文件夹下
public class CardCustomerInfo
{
    public string Number { get; set; } // 属性名可自定义,也可和原表字段保持一致
    public decimal Amount { get; set; }
    public int CustomerID { get; set; }
}

然后修改你的LINQ查询,返回这个DTO的集合,而不是匿名类型:

// 假设db是你的数据库上下文实例
var query = from card in db.Cards
            join customer in db.Customers on card.CustomerID equals customer.CustomerID
            select new CardCustomerInfo
            {
                Number = card.Number,
                Amount = card.Ammount,
                CustomerID = card.CustomerID
            };

// 填充DataGrid
dataGrid.ItemsSource = query.ToList();

最后在MouseDoubleClick事件里,就可以安全地强转SelectedItem了:

private void dataGrid_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
    var selectedInfo = dataGrid.SelectedItem as CardCustomerInfo;
    if (selectedInfo != null)
    {
        txtNumber.Text = selectedInfo.Number;
        txtAmount.Text = selectedInfo.Amount.ToString();
        // 如果需要显示CustomerID也可以直接取
        // txtCustomerID.Text = selectedInfo.CustomerID.ToString();
    }
}

这种方法的好处是编译时就有类型检查,不会因为属性名拼写错误导致运行时异常,后期维护也更方便。

2. 快速解决:使用dynamic类型

如果你只是想快速搞定,不想额外定义类,可以用C#的dynamic类型来绕过编译时类型检查:

private void dataGrid_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
    if (dataGrid.SelectedItem == null) return;

    dynamic selectedRow = dataGrid.SelectedItem;
    // 注意这里的属性名要和你LINQ匿名类型里的完全一致(包括大小写!)
    txtNumber.Text = selectedRow.number.ToString();
    txtAmount.Text = selectedRow.ammount.ToString();
}

这种方法简单直接,但缺点是没有编译时检查——如果匿名类型的属性名拼写错了,只有运行时才会报错,适合临时测试或者小型项目使用。

3. 不推荐:用反射提取属性

如果上面两种方法都不适用,还可以通过反射来读取匿名类型的属性值,但这种方法代码繁琐,性能也差,一般不推荐:

private void dataGrid_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
    var selectedItem = dataGrid.SelectedItem;
    if (selectedItem == null) return;

    var itemType = selectedItem.GetType();
    // 获取number属性值
    var numberValue = itemType.GetProperty("number")?.GetValue(selectedItem)?.ToString();
    // 获取ammount属性值
    var amountValue = itemType.GetProperty("ammount")?.GetValue(selectedItem)?.ToString();

    if (!string.IsNullOrEmpty(numberValue))
        txtNumber.Text = numberValue;
    if (!string.IsNullOrEmpty(amountValue))
        txtAmount.Text = amountValue;
}

总结一下:优先用强类型DTO的方法,兼顾安全性和可维护性;快速测试用dynamic;反射尽量避免使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:22:31