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

如何加速将PowerShell数组数据导入WPF DataGrid?

Optimizing DataGrid Bulk Import with PowerShell & XAML

Hey there! Let's fix that slow DataGrid item import you're dealing with. Your current loop-based approach is causing unnecessary UI updates and redundant object creation—here's a much more efficient way to handle bulk data loading:

First, Let's Clean Up the XAML

Your existing DataGrid has both AutoGenerateColumns="True" and manually defined columns, which will result in duplicate columns. Disable auto-generation since you've already specified the columns you need:

<DataGrid x:Name="DataGrid_DisabledAccounts" 
          Background="#FF616161" 
          Foreground="Black" 
          AutoGenerateColumns="False"  <!-- Changed from True to avoid duplicate columns -->
          SelectionMode="Extended">
    <DataGrid.Columns>
        <DataGridTextColumn Header="Name" Binding="{Binding Name}"/>
        <DataGridTextColumn Header="SamAccountName" Binding="{Binding SamAccountName}"/>
        <DataGridTextColumn Header="distinguishedName" Binding="{Binding distinguishedName}"/>
    </DataGrid.Columns>
</DataGrid>

Optimized PowerShell Code

The key issue with your current code is that adding items one-by-one and calling Items.Refresh() on each iteration forces the UI to redraw constantly. Instead, we'll use a WPF-friendly collection to load all data at once, then bind it to the DataGrid.

Step 1: Efficiently Fetch AD Data

First, optimize your AD query to avoid redundant property lookups (we'll fetch the Enabled property directly instead of implicitly querying ADUser twice):

# Get disabled users from the group (optimized AD call)
$Func_DisabledAccounts = Get-ADGroupMember -Identity $global:gbl_SrcGroup -Recursive | 
    ForEach-Object { Get-ADUser $_.SamAccountName -Properties Enabled } |
    Where-Object { -not $_.Enabled } |
    Select-Object Name, SamAccountName, distinguishedName

Step 2: Use ObservableCollection for Bulk Binding

WPF's ObservableCollection automatically notifies the UI of changes, so we can load all data into this collection first, then assign it to the DataGrid's ItemsSource in one go (no more manual refreshes!):

# Ensure WPF assemblies are loaded (run once if not already loaded)
Add-Type -AssemblyName PresentationFramework

# Create an ObservableCollection to hold our data
$accountCollection = New-Object System.Collections.ObjectModel.ObservableCollection[PSObject]

# Bulk add all items to the collection (this is fast because it doesn't trigger UI updates yet)
foreach ($account in $Func_DisabledAccounts) {
    $accountCollection.Add($account)
}

# Bind the entire collection to the DataGrid - UI updates once!
$DataGrid_DisabledAccounts.ItemsSource = $accountCollection

Why Your Original Approach Was Slow

  • Per-item UI updates: Calling AddChild() + Items.Refresh() in a loop forces the DataGrid to redraw after every single item, which is extremely inefficient for large datasets.
  • Redundant object creation: You were creating a $tmp object and using Add-Member unnecessarily—your Func_DisabledAccounts already contains objects with the exact properties you need.
  • Incorrect bulk method: AddChild() is designed for single elements, not collections. Setting ItemsSource is the correct way to bind an entire dataset to a DataGrid.

Bonus: Even Faster Collection Population

If you have a huge dataset, you can use a List<PSObject> first to load all items, then convert it to an ObservableCollection (this avoids the overhead of collection change notifications during population):

$accountList = New-Object System.Collections.Generic.List[PSObject]
$accountList.AddRange($Func_DisabledAccounts)

$accountCollection = New-Object System.Collections.ObjectModel.ObservableCollection[PSObject]($accountList)
$DataGrid_DisabledAccounts.ItemsSource = $accountCollection

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 10:42:56