WPF/ConvertTo-DataTemplate.ps1
function ConvertTo-DataTemplate { <# .Synopsis Converts the UIElement to a data template .Description Converts the UIElement to a data template by stripping its resources, outputting the control as XAML, and enclosing within <DateTemplate> tags .Example New-Image | ConvertTo-DataTemplate @{"Source" = "MySource"} -outputXaml .Example New-ListBox -ItemsSource { Get-Process } -ItemTemplate { New-StackPanel -Orientation Horizontal -Children { New-Label -Name ProcessName -FontSize 14 New-Label -Name Id -FontSize 8 } | ConvertTo-DataTemplate -binding @{ "ProcessName.Content" = "ProcessName" "Id.Content" = "Id" } } -show .Parameter control The UIElement to turn into a data .Parameter binding A dictionary of UIElements .Parameter outputXaml If set, will output the Xaml for the data template rather than the object #> param( [Parameter(ValueFromPipeline=$true)] [Windows.UIElement] $control, [Parameter(Position=0)] [Alias("DataBinding")] [Hashtable]$binding, [switch]$outputXaml, [switch]$AsItemTemplate, [Type]$TemplateType ) process { $control | Get-ChildControl | ForEach-Object { if ($_.Resources) { foreach ($kv in @($_.Resources.GetEnumerator())) { $null = $_.Resources.Remove($kv.Key) } } } $xaml = [Windows.Markup.XamlWriter]::Save($control) $xml = [xml]$xaml if ($binding) { $binding.GetEnumerator() | ForEach-Object { $value = $_.Value if ($_.Key -like "*.*" ) { $chunks = $_.Key.Split(".") $targetName = $chunks[0] $bind = $chunks[1] $xml | Select-Xml "//*" | Where-Object { $_.Node.Name -eq $targetName } | ForEach-Object { $_.Node.SetAttribute($bind, "{Binding $value}") } } else { $property = $_.Key $value = $_.Value $xml | Select-Xml "." | Foreach-Object { @($_.Node.GetEnumerator())[0].SetAttribute($property, "{Binding $value}") } } } } if ($TemplateType) { [Xml]$Template = [System.Windows.Markup.XamlWriter]::Save( (New-Object $TemplateType) ) $Template.DocumentElement.PrependChild( $Template.ImportNode($xml.DocumentElement, $true) ) | Out-Null $xaml = $Template.OuterXml } elseif ($AsItemTemplate) { $xaml = " <ItemTemplate xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'> $($xml.OuterXml) </ItemTemplate> " } else { $xaml = " <DataTemplate xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'> $($xml.OuterXml) </DataTemplate> " } if($debugPreference -ne 'SilentlyContinue') { Write-Debug "Template XAML: $xaml" } if ($outputXaml) { $strWrite = New-Object IO.StringWriter [xml]$newXml = $xaml $newXml.Save($strWrite) return "$strWrite" } else { [Windows.Markup.XamlReader]::Parse($xaml) } } } |