如何从PowerShell XAML GUI的DataGrid获取行列索引?
解决WPF DataGrid在PowerShell中获取点击/选中行列索引的问题
问题根源
WPF的DataGrid控件事件体系和WinForms的DataGridView完全不同,你尝试的MouseClick、CellClick都是WinForms专属事件,WPF里不存在这些方法,因此会触发报错。同时原脚本中CurrentColumn.DisplayIndex无法获取,是因为未正确触发单元格选中状态或CurrentColumn未完成初始化。
解决方案
使用WPF DataGrid原生支持的事件(如CellMouseDown、SelectedCellsChanged),并通过事件参数获取可靠的行列索引信息。
修改后的完整脚本
[xml]$xaml = @' <Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Name="Window" Title="Demo" WindowStartupLocation = "CenterScreen" SizeToContent="WidthAndHeight" ShowInTaskbar = "True"> <StackPanel Orientation="Vertical" Name="msiStackPanel"> <TextBlock Margin="20,20,20,20" HorizontalAlignment="Center" FontSize="14" FontWeight="Bold">List of Stuff</TextBlock> <DataGrid Name="myGrid" SelectionUnit="Cell"/> <Button Name="UpdateDatabaseButton" Content="Update Database" Margin="10" VerticalAlignment="Bottom" HorizontalAlignment="Right"/> </StackPanel> </Window> '@ # Set PowerShell variable for each named object in GUI Function Set-WpfVariables { param($children) ForEach ($child in $children.Children) { Set-WpfVariables -Children $child if (![String]::IsNullOrEmpty($child.Name)) { Write-Host "Set variable $($child.Name)" Set-Variable -Name $child.Name -Value $child -Scope global } } } # Build Window $reader=(New-Object System.Xml.XmlNodeReader $xaml) $Window=[Windows.Markup.XamlReader]::Load( $reader ) $controls = [System.Windows.LogicalTreeHelper]::GetChildren($window) Set-WpfVariables -Children $controls $myGrid = $window.FindName("myGrid") $UpdateDatabaseButton = $window.FindName("UpdateDatabaseButton") $myGrid.ItemsSource = get-process | Select-Object -First 5 # 绑定CellMouseDown事件,获取点击的单元格行列索引 $myGrid.add_CellMouseDown({ $cell = $args[0].OriginalSource while ($cell -isnot [System.Windows.Controls.DataGridCell] -and $cell -ne $null) { $cell = $cell.Parent } if ($cell -ne $null) { $rowIndex = $myGrid.ItemContainerGenerator.IndexFromContainer($cell.Parent) $columnIndex = $myGrid.Columns.IndexOf($cell.Column) Write-Host "点击的单元格: 行索引 $rowIndex, 列索引 $columnIndex" # 可在此处添加更新数据的逻辑 } }) # 绑定按钮点击事件,获取当前选中的单元格行列 $UpdateDatabaseButton.Add_Click({ if ($myGrid.SelectedCells.Count -gt 0) { $selectedCell = $myGrid.SelectedCells[0] $rowIndex = $myGrid.ItemContainerGenerator.IndexFromContainer($selectedCell.ItemContainer) $columnIndex = $myGrid.Columns.IndexOf($selectedCell.Column) Write-Host "选中的单元格: 行索引 $rowIndex, 列索引 $columnIndex" } else { Write-Host "未选中任何单元格" } }) $window.ShowDialog()
关键说明
- 事件选择:
CellMouseDown:鼠标点击单元格时触发,适合实时获取点击位置SelectedCellsChanged:选中单元格变化时触发,适合获取选中状态的单元格
- 行列索引获取逻辑:
- 通过事件参数的
OriginalSource向上遍历找到DataGridCell对象 - 用
ItemContainerGenerator.IndexFromContainer获取行索引 - 用
Columns.IndexOf获取列索引
- 通过事件参数的
- XAML修改:添加
SelectionUnit="Cell"确保可以选中单个单元格,方便获取准确的单元格索引
内容的提问来源于stack exchange,提问作者Koen van mullem
相关产品推荐
相关产品推荐

