如何获取PowerShell XAML WPF DataGrid行详情模板的标题
解决DataGrid行详情标题无法获取的问题
嗨,我来帮你搞定这个问题!核心原因很简单:DataGrid的行详情是用DataTemplate定义的模板化内容,它不属于DataGrid的主列集合,所以你用$datagrid.Columns或者$datagrid.Items肯定找不到这些标题——这俩API只针对DataGrid的主表格区域,而行详情是用户展开行之后才会渲染的独立UI块。
下面分两种场景给你解决方案:
场景1:直接从XAML源码里提取标题文本
如果你只是想拿到XAML里预先写好的那些标题(比如"Domain:"、"Disabled Machines:"),不需要等UI渲染出来,直接解析XAML的XML结构就行:
# 用XPath定位行详情模板里的所有TextBlock $rowDetailTextBlocks = $XAML.SelectNodes("//DataGrid.RowDetailsTemplate//TextBlock[@Text]") # 筛选出带冒号的标题文本(排除绑定数据的那些TextBlock) $rowDetailHeaders = $rowDetailTextBlocks | Where-Object { $_.Text -match ":$" } | ForEach-Object { $_.Text.TrimEnd(':') } # 输出结果 $rowDetailHeaders
运行这段代码会得到:
Domain Disabled Machines Servers
思路就是利用XPath查询,直接从XAML的XML节点里找到行详情模板中带有Text属性且以冒号结尾的TextBlock,再把文本末尾的冒号去掉,就是你要的标题了。
场景2:获取已经渲染出来的行详情标题(行展开后)
如果需要在用户展开某一行之后,拿到该行详情里的标题,那就得遍历DataGrid的可视化树,找到对应的UI元素。先写个通用的可视化树查找函数:
# 定义遍历可视化树的辅助函数 function Find-VisualChildren { param( [Parameter(Mandatory=$true)] [System.Windows.DependencyObject]$Parent, [Parameter(Mandatory=$true)] [Type]$ChildType ) for ($i = 0; $i -lt [System.Windows.Media.VisualTreeHelper]::GetChildrenCount($Parent); $i++) { $child = [System.Windows.Media.VisualTreeHelper]::GetChild($Parent, $i) if ($child.GetType() -eq $ChildType) { $child } # 递归查找子元素 Find-VisualChildren -Parent $child -ChildType $ChildType } } # 步骤1:获取当前选中行的容器 $selectedRow = $datagrid.ItemContainerGenerator.ContainerFromItem($datagrid.SelectedItem) # 步骤2:找到该行的行详情容器(必须先展开行才能找到) $rowDetailsPresenter = Find-VisualChildren -Parent $selectedRow -ChildType ([System.Windows.Controls.RowDetailsPresenter]) | Select-Object -First 1 # 步骤3:从行详情容器里筛选出加粗的标题TextBlock $rowDetailHeaders = Find-VisualChildren -Parent $rowDetailsPresenter -ChildType ([System.Windows.Controls.TextBlock]) | Where-Object { $_.FontWeight -eq 'Bold' } | ForEach-Object { $_.Text.TrimEnd(':') } # 输出结果 $rowDetailHeaders
注意点:
- 这段代码必须在行已经被展开之后执行,不然
RowDetailsPresenter还没被创建,会返回空结果。 - 我们用
FontWeight -eq 'Bold'来区分标题和数据文本块,这和你XAML里的定义完全匹配(标题都是加粗的)。
额外说明
为什么$datagrid.Items不行?因为Items里存的是你绑定的数据对象(比如那个pscustomobject),这些对象只有数据属性(Domain、Servers这些),根本没有UI层面的标题信息——标题是XAML模板里的UI元素,和数据对象是完全分离的,所以从数据对象里肯定挖不出来。
内容的提问来源于stack exchange,提问作者Graham J
相关产品推荐
相关产品推荐

