我尝试使用Powershell在WPF数据网格中每行的开头添加一个图标。我不想存储图像,因此我使用base64进行转换。
以下是显示带有图标+进程名称的数据网格的代码:
Add-Type -AssemblyName PresentationFramework, System.Windows.Forms, System.Drawing
[xml]$xaml=@"
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="MainWindow" Height="410" Width="670" WindowStartupLocation="CenterScreen">
<Grid>
<DataGrid x:Name="dgResults" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Icon" IsReadOnly="True">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Image x:Name="icon" Source="{Binding Icon}" Width="24" Height="24" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Binding="{Binding Process}" Header="Process" IsReadOnly="True"/>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>
"@
$reader=(New-Object System.Xml.XmlNodeReader $xaml)
$Window=[Windows.Markup.XamlReader]::Load($reader)
$xaml.SelectNodes("//*[@*[contains(translate(name(.),'n','N'),'x:Name')]]") | ForEach-Object{
Set-Variable -Name ($_.Name) -Value $Window.FindName($_.Name)
}
#start conversion
$strBase64 = [convert]::ToBase64String([System.Drawing.Icon]::ExtractAssociatedIcon("C:\windows\System32\cmd.exe"))
$bitmap = New-Object System.Windows.Media.Imaging.BitmapImage
$bitmap.BeginInit()
$bitmap.StreamSource = [System.IO.MemoryStream][System.Convert]::FromBase64String($strBase64)
$bitmap.EndInit()
$bitmap.Freeze()
#end conversion
$arrayItems = @()
Get-Process | Select-Object Name -First 5 | ForEach-Object{
$itemObject = New-Object System.Object
$itemObject | Add-Member -Type NoteProperty -Name "Icon" -Value $bitmap
$itemObject | Add-Member -Type NoteProperty -Name "Process" -Value $_.Name
$arrayItems += $itemObject
}
$dgResults.ItemsSource = $arrayItems
#Display Form
$Window.ShowDialog() | Out-Null
Base64字符串的转换在这里完成:
#start conversion
$strBase64 = [convert]::ToBase64String([System.Drawing.Icon]::ExtractAssociatedIcon("C:\windows\System32\cmd.exe"))
$bitmap = New-Object System.Windows.Media.Imaging.BitmapImage
$bitmap.BeginInit()
$bitmap.StreamSource = [System.IO.MemoryStream][System.Convert]::FromBase64String($strBase64)
$bitmap.EndInit()
$bitmap.Freeze()
#end conversion
$bitmap
对象返回System.Windows.Media.Imaging.BitmapImage
当我使用$Window.Icon = $bitmap
更改窗口徽标时,没有问题,图标设置正确,但是当我存储它并使用来自ItemsSource
的{{1}}来调用数据时(包含图标+进程名称),图像不会出现在每行的开头。
你有什么想法吗?
感谢。
$arrayItems
答案 0 :(得分:1)
所以这个问题与WPF如何真正支持图标格式有关。您需要将该格式转换为WPF Image标签可读的格式。请改用以下代码。您正在使用的是什么
Add-Type -AssemblyName PresentationFramework, System.Windows.Forms, System.Drawing
[xml]$xaml=@"
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="MainWindow" Height="410" Width="670" WindowStartupLocation="CenterScreen">
<Grid>
<DataGrid x:Name="dgResults" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Icon" IsReadOnly="True">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Image x:Name="icon" Source="{Binding Icon}" Width="24" Height="24" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Binding="{Binding Process}" Header="Process" IsReadOnly="True"/>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>
"@
$reader=(New-Object System.Xml.XmlNodeReader $xaml)
$Window=[Windows.Markup.XamlReader]::Load($reader)
$xaml.SelectNodes("//*[@*[contains(translate(name(.),'n','N'),'x:Name')]]") | ForEach-Object{
Set-Variable -Name ($_.Name) -Value $Window.FindName($_.Name)
}
#start conversion
$icon = [System.Drawing.Icon]::ExtractAssociatedIcon("C:\windows\System32\cmd.exe")
$bmp = $icon.ToBitmap()
$stream = new-object System.IO.MemoryStream
$bmp.Save($stream, [System.Drawing.Imaging.ImageFormat]::Png)
$imageSource = [System.Windows.Media.Imaging.BitmapFrame]::Create($stream);
#end conversion
$arrayItems = @()
Get-Process | Select-Object Name -First 5 | ForEach-Object{
$itemObject = New-Object System.Object
$itemObject | Add-Member -Type NoteProperty -Name "Icon" -Value $imageSource
$itemObject | Add-Member -Type NoteProperty -Name "Process" -Value $_.Name
$arrayItems += $itemObject
}
$dgResults.ItemsSource = $arrayItems
#Display Form
$Window.ShowDialog() | Out-Null
区别在于转换为PNG ......
$icon = [System.Drawing.Icon]::ExtractAssociatedIcon("C:\windows\System32\cmd.exe")
$bmp = $icon.ToBitmap()
$stream = new-object System.IO.MemoryStream
$bmp.Save($stream, [System.Drawing.Imaging.ImageFormat]::Png)
$imageSource = [System.Windows.Media.Imaging.BitmapFrame]::Create($stream);