VB.NET DataGrid绑定XML子节点与数据过滤技术问题咨询
解决VB.NET DataGridView绑定XML嵌套节点及数据过滤问题
一、绑定嵌套XML节点(如client/clientname)到DataGridView
当你用ds.ReadXML()读取嵌套XML时,DataSet会自动生成多个关联的DataTable(比如task、client、org、substatus),直接绑定task表无法直接访问子节点字段。这里有两种实用方案:
方案1:用DataColumn表达式关联子表
利用DataSet自动创建的表关系,给task表添加计算列指向子表字段:
' 读取XML后获取对应表 Dim taskTable As DataTable = ds.Tables("task") ' 添加clientname计算列 If Not taskTable.Columns.Contains("ClientName") Then Dim clientNameCol As New DataColumn("ClientName", GetType(String)) ' 通过自动生成的表关系关联子表字段,格式:ChildTableName.ColumnName clientNameCol.Expression = "client.clientname" taskTable.Columns.Add(clientNameCol) End If ' 同理添加orgname计算列 If Not taskTable.Columns.Contains("OrgName") Then Dim orgNameCol As New DataColumn("OrgName", GetType(String)) orgNameCol.Expression = "org.orgname" taskTable.Columns.Add(orgNameCol) End If ' 绑定DataGridView列 DataGridView1.Columns("ClientNameCol").DataPropertyName = "ClientName" DataGridView1.Columns("OrgNameCol").DataPropertyName = "OrgName"
方案2:扁平化数据(推荐,更直观)
用LINQ to DataSet把嵌套数据整合成单张扁平表,所有字段可直接绑定:
' 先获取DataSet里的各个表 Dim taskTbl = ds.Tables("task").AsEnumerable() Dim clientTbl = ds.Tables("client").AsEnumerable() Dim orgTbl = ds.Tables("org").AsEnumerable() Dim substatusTbl = ds.Tables("substatus").AsEnumerable() ' LINQ查询扁平化数据 Dim flatTasks = From task In taskTbl Join client In clientTbl On task("task_id") Equals client("task_id") ' 关联键是DataSet自动生成的外键 Join org In orgTbl On task("task_id") Equals org("task_id") Join sub In substatusTbl On task("task_id") Equals sub("task_id") Select New With { .ContactName = task("contactname"), .ClientName = client("clientname"), .OrgName = org("orgname"), .Status = task("status"), .SubStatus = sub("substatus"), .JobNumber = task("jobnumber") ' 按需添加其他字段 } ' 转换为DataTable Dim flatTable As New DataTable() flatTable.Columns.AddRange({ New DataColumn("ContactName", GetType(String)), New DataColumn("ClientName", GetType(String)), New DataColumn("OrgName", GetType(String)), New DataColumn("Status", GetType(String)), New DataColumn("SubStatus", GetType(String)), New DataColumn("JobNumber", GetType(String)) }) For Each item In flatTasks flatTable.Rows.Add(item.ContactName, item.ClientName, item.OrgName, item.Status, item.SubStatus, item.JobNumber) Next ' 绑定到DataGridView DataGridView1.DataSource = flatTable
二、过滤不符合条件的行
需要过滤两种情况:org/orgname不匹配指定公司名称、substatus/substatus不为Not Started或In Progress。
基于原DataSet表的过滤
通过查询子表获取无效TaskID,再删除对应行:
Dim targetCompany As String = "目标公司名称" Dim taskTable As DataTable = ds.Tables("task") ' 1. 获取orgname不匹配的TaskID Dim invalidOrgIds = From org In ds.Tables("org").AsEnumerable() Where org("orgname").ToString() <> targetCompany Select org("task_id") ' 2. 获取substatus不符合的TaskID Dim invalidSubStatusIds = From sub In ds.Tables("substatus").AsEnumerable() Where sub("substatus").ToString() <> "Not Started" AndAlso sub("substatus").ToString() <> "In Progress" Select sub("task_id") ' 3. 合并无效ID并倒序删除(避免索引混乱) Dim invalidIds = invalidOrgIds.Union(invalidSubStatusIds).ToList() For i = taskTable.Rows.Count - 1 To 0 Step -1 Dim taskId = taskTable.Rows(i)("task_id") If invalidIds.Contains(taskId) Then taskTable.Rows(i).Delete() End If Next taskTable.AcceptChanges() DataGridView1.DataSource = taskTable
基于扁平化表的过滤
在LINQ查询时直接添加过滤条件,一步到位:
Dim targetCompany As String = "目标公司名称" Dim filteredFlatTasks = From task In ds.Tables("task").AsEnumerable() Join client In ds.Tables("client").AsEnumerable() On task("task_id") Equals client("task_id") Join org In ds.Tables("org").AsEnumerable() On task("task_id") Equals org("task_id") Join sub In ds.Tables("substatus").AsEnumerable() On task("task_id") Equals sub("task_id") ' 添加过滤条件 Where org("orgname").ToString() = targetCompany _ AndAlso (sub("substatus").ToString() = "Not Started" OrElse sub("substatus").ToString() = "In Progress") Select New With { .ContactName = task("contactname"), .ClientName = client("clientname"), .OrgName = org("orgname"), .Status = task("status"), .SubStatus = sub("substatus"), .JobNumber = task("jobnumber") } ' 后续转换为DataTable并绑定的步骤和方案2一致
小提示
不确定DataSet生成的表名或关联键?可以在调试时查看ds.Tables集合,或者用ds.Relations查看自动创建的表关系。
内容的提问来源于stack exchange,提问作者Chris Rutherfurd
相关产品推荐
相关产品推荐

