{"id":6101,"date":"2008-05-24T19:00:00","date_gmt":"2008-05-24T19:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/powershell\/2008\/05\/24\/wpf-powershell-part-4-xaml-show-control\/"},"modified":"2019-02-18T13:15:54","modified_gmt":"2019-02-18T20:15:54","slug":"wpf-powershell-part-4-xaml-show-control","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/powershell\/wpf-powershell-part-4-xaml-show-control\/","title":{"rendered":"WPF &#038; PowerShell &#8212; Part 4 (XAML &#038; Show-Control)"},"content":{"rendered":"<p>We&#8217;re not halfway through our week of WPF, and I&#8217;m pretty sure at this point that you have an all right grounding in the basics of WPF &amp; PowerShell, but so far, the scripts haven&#8217;t really been very much like most PowerShell scripts, and the UIs have not been like most WPF UIs.&nbsp; The scripts have been a little odd because they haven&#8217;t really made use of a common convention of PowerShell&#8230; the pipeline.&nbsp;&nbsp; The WPF examples have also been a little verbose because they do not include any XAML.<\/p>\n<p>XAML is an XML format you can use to write user interfaces that use WPF.&nbsp; Because WPF is very property oriented, it is often more concise to write an interface using XAML than it is to write it by setting properties in PowerShell.&nbsp; XAML also has many developer tools, such as Microsoft Blend and Visual Studio, to help design your application.&nbsp; However, XAML cannot contain event handlers.&nbsp; In order to make writing interfaces in XAML easier, I&#8217;ve written Show-Control. a function that takes a control, shape, or XAML document from the pipeline and a dictionary of ScriptBlocks as the event handlers.&nbsp; Show-Control is a little large (~ 90 lines), so lets walk through how we can make the examples shorter with XAML &amp; Show-Control.&nbsp; Show-Control&#8217;s source code will be at the bottom.<\/p>\n<p>Here are all of the examples from Part 1, Part 2, and Part 3, redone to use Show-Control<\/p>\n<p><strong>Large Font Hello World (was 7 lines, now 1 line):<\/strong><\/p>\n<p>&#8220;&lt;Label xmlns=&#8217;<a href=\"http:\/\/schemas.microsoft.com\/winfx\/2006\/xaml\/presentation'\">http:\/\/schemas.microsoft.com\/winfx\/2006\/xaml\/presentation&#8217;<\/a> FontSize=&#8217;24&#8217;&gt;Hello World&lt;\/Label&gt;&#8221; | Show-Control <\/p>\n<p><strong>InkCanvas (was 7 lines, now 1 line):<\/strong><\/p>\n<p>&#8220;&lt;InkCanvas xmlns=&#8217;http:\/\/schemas.microsoft.com\/winfx\/2006\/xaml\/presentation&#8217; \/&gt;&#8221; | Show-Control <\/p>\n<p><strong>Random Circle (was 9 lines, now 6 lines)<\/strong><\/p>\n<p>$circleSize = Get-Random -min 200 -max 450 <br \/>$color = &#8220;Red&#8221;, &#8220;Green&#8221;,&#8221;Blue&#8221;,&#8221;Orange&#8221;,&#8221;Yellow&#8221; | Get-Random <br \/>&#8220;&lt;Ellipse xmlns=&#8217;<a href=\"http:\/\/schemas.microsoft.com\/winfx\/2006\/xaml\/presentation'\">http:\/\/schemas.microsoft.com\/winfx\/2006\/xaml\/presentation&#8217;<\/a> <br \/>&nbsp; Width=&#8217;$circleSize&#8217; <br \/>&nbsp; Height=&#8217;$circleSize&#8217; <br \/>&nbsp; Fill=&#8217;$color&#8217; \/&gt;&#8221; |&nbsp; Show-Control<\/p>\n<p><strong>Slider (was 8 lines, now 1 line)<\/strong><\/p>\n<p>&#8220;&lt;Slider xmlns=&#8217;http:\/\/schemas.microsoft.com\/winfx\/2006\/xaml\/presentation&#8217; Minimum=&#8217;1&#8242; Maximum=&#8217;10&#8217;\/&gt;&#8221;| Show-Control <\/p>\n<p><strong>Label &amp; Textbox (was 11 lines, now 6 lines) <\/strong><\/p>\n<p>@&#8221; <br \/>&lt;StackPanel xmlns=&#8217;<a href=\"http:\/\/schemas.microsoft.com\/winfx\/2006\/xaml\/presentation'\">http:\/\/schemas.microsoft.com\/winfx\/2006\/xaml\/presentation&#8217;<\/a>&gt; <br \/>&lt;Label FontSize=&#8217;20&#8217;&gt;Type Something&lt;\/Label&gt; <br \/>&lt;TextBox \/&gt; <br \/>&lt;\/StackPanel&gt; <br \/>&#8220;@ |&nbsp; Show-Control<\/p>\n<p><strong>Click &amp; Close (was 6 lines, now 3 lines)<\/strong><\/p>\n<p>@&#8221; <br \/>&lt;Button FontSize=&#8217;20&#8217; xmlns=&#8217;<a href=\"http:\/\/schemas.microsoft.com\/winfx\/2006\/xaml\/presentation'\">http:\/\/schemas.microsoft.com\/winfx\/2006\/xaml\/presentation&#8217;<\/a>&gt;Click Me&lt;\/Button&gt; <br \/>&#8220;@ | Show-Control @{&#8220;Click&#8221; = {$window.close()}}<\/p>\n<p><strong>Select-Command (was 26 lines, now 19)<\/strong><\/p>\n<p>@&#8221; <br \/>&lt;StackPanel xmlns=&#8217;<a href=\"http:\/\/schemas.microsoft.com\/winfx\/2006\/xaml\/presentation'\">http:\/\/schemas.microsoft.com\/winfx\/2006\/xaml\/presentation&#8217;<\/a>&gt; <br \/>&lt;Label FontSize=&#8217;14&#8217;&gt;Type a Command&lt;\/Label&gt; <br \/>&lt;TextBox Name=&#8221;CommandTextBox&#8221;\/&gt; <br \/>&lt;ListBox Name=&#8221;CommandListBox&#8221; Width=&#8217;200&#8242; Height=&#8217;200&#8217;\/&gt; <br \/>&lt;Button Name=&#8221;SelectCommandButton&#8221; FontSize=&#8217;14&#8217;&gt;Select Command&lt;\/Button&gt; <br \/>&lt;\/StackPanel&gt; <br \/>&#8220;@ | Show-Control @{ <br \/>&nbsp;&nbsp; &#8220;CommandTextBox.TextChanged&#8221; = {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $listBox = $window.Content.FindName(&#8220;CommandListBox&#8221;) <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $textBox = $window.Content.FindName(&#8220;CommandTextBox&#8221;) <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $listBox.ItemsSource = @(Get-Command &#8220;*$($textbox.Text)*&#8221; | % { $_.Name }) <br \/>&nbsp;&nbsp; } <br \/>&nbsp;&nbsp; &#8220;CommandListBox.SelectionChanged&#8221; = { <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $textBox = $window.Content.FindName(&#8220;CommandTextBox&#8221;) <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $textBox.Text = $this.SelectedItem <br \/>&nbsp;&nbsp; } <br \/>&nbsp;&nbsp; &#8220;SelectCommandButton.Click&#8221; = {$window.Close()} <br \/>}<\/p>\n<p><strong>Drag &amp; Drop<\/strong> <strong>(was 33 lines, now 31)<\/strong><\/p>\n<p>@&#8221; <br \/>&lt;StackPanel xmlns=&#8217;<a href=\"http:\/\/schemas.microsoft.com\/winfx\/2006\/xaml\/presentation'\">http:\/\/schemas.microsoft.com\/winfx\/2006\/xaml\/presentation&#8217;<\/a>&gt; <br \/>&lt;Label FontSize=&#8217;14&#8217;&gt;Drag Scripts Here, DoubleClick to Run&lt;\/Label&gt; <br \/>&lt;ListBox Name=&#8221;CommandListBox&#8221; AllowDrop=&#8217;True&#8217; Height=&#8217;200&#8217;\/&gt; <br \/>&lt;Button Name=&#8221;RunCommandButton&#8221; FontSize=&#8217;14&#8217;&gt;Run File&lt;\/Button&gt; <br \/>&lt;Button Name=&#8221;ClearCommandButton&#8221; FontSize=&#8217;14&#8217;&gt;Clear List&lt;\/Button&gt; <br \/>&lt;\/StackPanel&gt; <br \/>&#8220;@ | Show-Control @{ <br \/>&nbsp;&nbsp; &#8220;CommandListBox.MouseDoubleClick&#8221; = { <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Invoke-Expression &#8220;$($this.SelectedItem)&#8221; -ea SilentlyContinue <br \/>&nbsp;&nbsp; } <br \/>&nbsp;&nbsp; &#8220;CommandListBox.Drop&#8221; = { <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $files = $_.Data.GetFileDropList() <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; foreach ($file in $files) { <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ($file -is [IO.FileInfo]) { <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $displayedFiles = $file <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else { <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $displayedFiles += dir $file -recurse | ? { $_ -is [IO.FileInfo]} | % { $_.FullName } <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $listBox.ItemsSource = $displayedFiles | sort&nbsp;&nbsp;&nbsp; <br \/>&nbsp;&nbsp; } <br \/>&nbsp;&nbsp; &#8220;RunCommandButton.Click&#8221; = { <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $listBox = $window.Content.FindName(&#8220;CommandListBox&#8221;) <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Invoke-Expression &#8220;$($listbox.SelectedItem)&#8221; -ea SilentlyContinue <br \/>&nbsp;&nbsp; } <br \/>&nbsp;&nbsp; &#8220;ClearCommandButton.Click&#8221; = { <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $window.Content.FindName(&#8220;CommandListBox&#8221;).ItemsSource=@() <br \/>&nbsp;&nbsp; } <br \/>}<\/p>\n<p>Finally, in order to make it easier for you to script WPF with PowerShell, I&#8217;m going to give you the Show-Control function that helped make our scripts shorter.&nbsp; I would recommend putting this function in a module file or your profile, so it&#8217;s always there when you need it:<\/p>\n<p><strong>Show-Control<\/strong><\/p>\n<p># Displays one or more controls.<br \/># Controls are piped to Show-Control as XAML or as a .NET object.<br \/># Events are passed as a dictionary of name\/scriptblocks<br \/># Event Hashtable keys can be like<br \/>#&nbsp;&nbsp; EVENTNAME (event on the object piped to Show-Control)<br \/>#&nbsp;&nbsp; TARGET.EVENTNAME (event on the named object within the control)<br \/>#&nbsp;&nbsp; WINDOW.EVENTNAME (event on the window)<br \/>function Show-Control { <br \/>&nbsp; cmdlet -DefaultParameterSet VisualElement<br \/>&nbsp; <br \/>&nbsp;&nbsp; param( <br \/>&nbsp;&nbsp; [Parameter(Mandatory=$true, <br \/>&nbsp;&nbsp; ParameterSetName=&#8221;VisualElement&#8221;, <br \/>&nbsp;&nbsp; ValueFromPipeline=$true, <br \/>&nbsp;&nbsp; ValueFromPipelineByPropertyName=$true)]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br \/>&nbsp;&nbsp; [Windows.Media.Visual] <br \/>&nbsp;&nbsp; $control,&nbsp;&nbsp;&nbsp;&nbsp; <br \/>&nbsp;&nbsp; [Parameter(Mandatory=$true, <br \/>&nbsp;&nbsp; ParameterSetName=&#8221;Xaml&#8221;, <br \/>&nbsp;&nbsp; ValueFromPipeline=$true, <br \/>&nbsp;&nbsp; ValueFromPipelineByPropertyName=$true)]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br \/>&nbsp;&nbsp; [string] <br \/>&nbsp;&nbsp; $xaml,&nbsp;&nbsp;&nbsp;&nbsp; <br \/>&nbsp;&nbsp; [Parameter(ValueFromPipelineByPropertyName=$true,Position=0)]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br \/>&nbsp;&nbsp; [Hashtable] <br \/>&nbsp;&nbsp; $event, <br \/>&nbsp;&nbsp; [Hashtable] <br \/>&nbsp;&nbsp; $windowProperties <br \/>&nbsp;&nbsp; ) <\/p>\n<p>&nbsp;&nbsp; Begin <br \/>&nbsp;&nbsp; { <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $window = New-Object Windows.Window <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $window.SizeToContent = &#8220;WidthAndHeight&#8221; <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ($windowProperties) { <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; foreach ($kv in $windowProperties.GetEnumerator()) { <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $window.&#8221;$($kv.Key)&#8221; = $kv.Value <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $visibleElements = @() <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $windowEvents = @() <br \/>&nbsp;&nbsp; } <\/p>\n<p>&nbsp;&nbsp; Process <br \/>&nbsp;&nbsp; {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; switch ($psCmdlet.ParameterSetName) <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;Xaml&#8221; { <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $f = [System.xml.xmlreader]::Create([System.IO.StringReader] $xaml) <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $visibleElements+=([system.windows.markup.xamlreader]::load($f))&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;VisualElement&#8221; { <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $visibleElements+=$control <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ($event) { <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $element = $visibleElements[-1]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; foreach ($evt in $event.GetEnumerator()) { <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # If the event name is like *.*, it is an event on a named target, otherwise, it&#8217;s on any of the events on the top level object <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ($evt.Key.Contains(&#8220;.&#8221;)) { <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $targetName = $evt.Key.Split(&#8220;.&#8221;)[1].Trim() <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ($evt.Key -like &#8220;Window.*&#8221;) { <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $target = $window <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else { <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $target = ($visibleElements[-1]).FindName(($evt.Key.Split(&#8220;.&#8221;)[0]))&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else { <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $target = $visibleElements[-1] <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $targetName = $evt.Key <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $target | Get-Member -type Event | <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ? { $_.Name -eq $targetName } | <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; % { <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $eventMethod = $target.&#8221;add_$targetName&#8221; <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $eventMethod.Invoke($evt.Value) <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <br \/>&nbsp;&nbsp;&nbsp; } <\/p>\n<p>&nbsp;&nbsp;&nbsp; End <br \/>&nbsp;&nbsp;&nbsp; { <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ($visibleElements.Count -gt 1) { <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $wrapPanel = New-Object Windows.Controls.WrapPanel <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $visibleElements | % { $null = $wrapPanel.Children.Add($_) } <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $window.Content = $wrapPanel <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else { <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ($visibleElements) { <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $window.Content = $visibleElements[0] <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $null = $window.ShowDialog() <br \/>&nbsp;&nbsp;&nbsp; } <br \/>}<\/p>\n<p>Now that I&#8217;ve introduced you to XAML, and given you a nice function to make using WPF in PowerShell, we&#8217;re ready to really start making some functions that make WPF controls.&nbsp; Stay tuned.<\/p>\n<p>Hope this helps,<\/p>\n<p>James Brundage [MSFT]<\/p>\n","protected":false},"excerpt":{"rendered":"<p>We&#8217;re not halfway through our week of WPF, and I&#8217;m pretty sure at this point that you have an all right grounding in the basics of WPF &amp; PowerShell, but so far, the scripts haven&#8217;t really been very much like most PowerShell scripts, and the UIs have not been like most WPF UIs.&nbsp; The scripts [&hellip;]<\/p>\n","protected":false},"author":600,"featured_media":13641,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[248,313,360],"class_list":["post-6101","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-powershell","tag-powershell","tag-show-control","tag-wpf"],"acf":[],"blog_post_summary":"<p>We&#8217;re not halfway through our week of WPF, and I&#8217;m pretty sure at this point that you have an all right grounding in the basics of WPF &amp; PowerShell, but so far, the scripts haven&#8217;t really been very much like most PowerShell scripts, and the UIs have not been like most WPF UIs.&nbsp; The scripts [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/posts\/6101","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/users\/600"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/comments?post=6101"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/posts\/6101\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/media\/13641"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/media?parent=6101"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/categories?post=6101"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/tags?post=6101"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}