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

PowerShell+WPF开发DataGrid:图片无法显示如何解决?

解决WPF DataGrid中内存图片无法显示的问题

你的代码存在几个关键问题导致图片无法显示,以下是修正后的完整代码及问题说明:

修正后的代码

Add-Type -AssemblyName PresentationCore, PresentationFramework, WindowsBase, System.Drawing

# 转换图片为BitmapSource(修复流处理和缓存选项)
function Convert-ImageFileToBitmapSource {
    param (
        [string] $ImagePath
    )

    $bitmap = New-Object System.Drawing.Bitmap($ImagePath)
    $bitmapStream = New-Object System.IO.MemoryStream
    try {
        $bitmap.Save($bitmapStream, [System.Drawing.Imaging.ImageFormat]::Png)
        # 重置流指针到起始位置,否则BitmapSource读取不到内容
        $bitmapStream.Seek(0, [System.IO.SeekOrigin]::Begin) | Out-Null

        $bitmapSource = New-Object System.Windows.Media.Imaging.BitmapImage
        $bitmapSource.BeginInit()
        $bitmapSource.StreamSource = $bitmapStream
        # 设置缓存选项为OnLoad,确保立即加载图片并脱离流依赖
        $bitmapSource.CacheOption = [System.Windows.Media.Imaging.BitmapCacheOption]::OnLoad
        $bitmapSource.EndInit()
        # 冻结BitmapSource提升性能并允许跨线程访问(可选)
        $bitmapSource.Freeze()
    }
    finally {
        $bitmap.Dispose()
        # 不要在这里关闭/释放流,OnLoad缓存后流已不再需要,但提前释放会导致加载失败
    }

    return $bitmapSource
}

# 使用匿名对象列表替代DataTable(避免DataTable对复杂类型绑定的限制)
$items = @(
    [PSCustomObject]@{
        Name = "Icon"
        Icon = Convert-ImageFileToBitmapSource -ImagePath "C:\Example\Icon.png"
    }
)

# WPF XAML内容(保持原结构不变)
[xml]$xaml = @"
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Image in DataGrid Example" Height="400" Width="600">
    <Grid>
        <DataGrid Name="myGrid" AutoGenerateColumns="False" ItemsSource="{Binding}">
            <DataGrid.Columns>
                <DataGridTextColumn Header="Name" Binding="{Binding Name}" Width="*"/>
                <DataGridTemplateColumn Header="Icon">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <Image Source="{Binding Icon}" Width="32" Height="32" />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>
"@

# 加载XAML并设置数据上下文
$reader = New-Object System.Xml.XmlNodeReader $xaml
$window = [Windows.Markup.XamlReader]::Load($reader)
$window.DataContext = $items
$window.ShowDialog() | Out-Null

关键问题说明

  • 流指针未重置:将Bitmap保存到MemoryStream后,流的读写指针停在末尾,BitmapSource无法读取到有效内容,必须用Seek(0, SeekOrigin::Begin)重置到起始位置。
  • BitmapSource缓存选项缺失:默认情况下BitmapSource会延迟加载流内容,当函数执行完毕后MemoryStream被GC回收,图片就无法加载。设置CacheOption = BitmapCacheOption::OnLoad会让BitmapSource立即加载并缓存图片数据,不再依赖原流。
  • DataTable类型绑定限制:DataTable对WPF绑定复杂CLR类型(如BitmapSource)的支持有限,改用PSCustomObject组成的列表可以避免这个问题,让绑定更可靠。
  • 资源释放时机:不要在函数内提前关闭MemoryStream,OnLoad缓存完成后流才可以安全释放,finally块中只需要释放原Bitmap即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 05:54:57