C# LINQ:如何用WPF DataGrid选中行的Country字段筛选数据?
解决WPF DataGrid选中行后访问匿名类型属性的问题
嘿,我来帮你搞定这个问题!你遇到的麻烦是因为第一个查询返回的是匿名类型,而GridOverview.SelectedItem的编译时类型是object——编译器根本不知道它有Country这个属性,所以直接写selectedRow.Country会报错。下面给你两种靠谱的解决办法:
方法一:使用动态类型(dynamic)
最简单的临时方案是把selectedRow声明为dynamic,这样编译器会在运行时解析属性:
// 把selectedRow转为dynamic类型 dynamic selectedRow = GridOverview.SelectedItem; var query = from c in db.Customers join o in db.Orders on c.CustomerID equals o.CustomerID join od in db.Order_Details on o.OrderID equals od.OrderID // 现在可以直接访问selectedRow.Country了 where c.Country == selectedRow.Country group new {c, o, od} by c.CompanyName into cByName orderby cByName.Sum(ood => ood.od.UnitPrice * ood.od.Quantity) descending select new { CompanyName = cByName.Key, Total = cByName.Sum(ood => ood.od.UnitPrice * ood.od.Quantity) };
⚠️ 注意:这种方法没有编译时检查,如果属性名写错了,只有运行时才会报错,适合快速测试,但不推荐在正式项目里大量使用。
方法二:创建强类型实体类(推荐)
更安全可靠的方式是定义一个明确的类来代替匿名类型,这样编译器能帮你做类型检查:
1. 先创建一个实体类
public class CountrySalesSummary { public string Country { get; set; } public decimal TotalSales { get; set; } }
2. 修改第一个查询,返回这个类的实例
var query2 = from o in db.Orders join od in db.Order_Details on o.OrderID equals od.OrderID group new { o, od } by o.ShipCountry into oByCountry orderby oByCountry.Sum(ood => ood.od.UnitPrice * ood.od.Quantity) descending select new CountrySalesSummary { Country = oByCountry.Key, TotalSales = oByCountry.Sum(ood => ood.od.UnitPrice * ood.od.Quantity) }; // 绑定到DataGrid GridOverview.ItemsSource = query2;
3. 选中行时转为强类型
// 转为我们定义的CountrySalesSummary类型,同时做null检查 var selectedRow = GridOverview.SelectedItem as CountrySalesSummary; if (selectedRow != null) { var query = from c in db.Customers join o in db.Orders on c.CustomerID equals o.CustomerID join od in db.Order_Details on o.OrderID equals od.OrderID // 这里可以安全访问selectedRow.Country,编译器会检查属性名 where c.Country == selectedRow.Country group new {c, o, od} by c.CompanyName into cByName orderby cByName.Sum(ood => ood.od.UnitPrice * ood.od.Quantity) descending select new { CompanyName = cByName.Key, Total = cByName.Sum(ood => ood.od.UnitPrice * ood.od.Quantity) }; // 把查询结果绑定到对应的控件,比如另一个DataGrid // CustomerGrid.ItemsSource = query; }
这种方法不仅能避免类型错误,代码可读性也更高,是正式项目里的最佳实践。
额外提醒
如果你不想定义新类,也可以用反射来获取Country属性的值,但这种方式代码繁琐且性能差,一般不推荐使用,就不展开讲啦。
内容的提问来源于stack exchange,提问作者SaraD
相关产品推荐
相关产品推荐

