Im trying to make a powershellscript using XAML Objects, that can be used to configure AD-Users.
My goal right now is to add a live search for a specific textbox. The script uses the input from the textbox, compares it to AD-Users and displays the output in a listbox. What I need is an eventhandler, that activates when I click any Item in the listbox
The last part is the relevant piece.
I'm grateful for any help.
$inputXML = #"
<Window x:Class="WpfApplication3.MainWindow"
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"
xmlns:local="clr-namespace:WpfApplication3"
mc:Ignorable="d"
Title="HHI Helpdesk Helper" Height="350" Width="654.604" Icon="C:\Users\hoesl\Pictures\logo.png" WindowStartupLocation="CenterScreen">
<Grid Background="#FFA0A0A0">
<TabControl x:Name="tabControl" HorizontalAlignment="Left" Height="301" Margin="10,10,0,0" VerticalAlignment="Top" Width="628">
<TabItem Header="Enable Admin Account">
<Grid Background="#FFE5E5E5">
<Label x:Name="label" Content="User : " HorizontalAlignment="Left" Margin="47,10,0,0" VerticalAlignment="Top"/>
<Label x:Name="label1" Content="Service-Tag : " HorizontalAlignment="Left" Margin="10,53,0,0" VerticalAlignment="Top"/>
<Label x:Name="label2" Content="Set Password : " HorizontalAlignment="Left" Margin="2,95,0,0" VerticalAlignment="Top"/>
<TextBox x:Name="textBox1" HorizontalAlignment="Left" Height="23" Margin="95,57,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/>
<TextBox x:Name="textBox2" HorizontalAlignment="Left" Height="23" Margin="95,99,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/>
<Calendar HorizontalAlignment="Left" Margin="434,10,0,0" VerticalAlignment="Top"/>
<TextBlock x:Name="textBlock" HorizontalAlignment="Left" Margin="10,127,0,0" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Top" Height="116" Width="410">
<TextBlock.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="Black" Offset="0"/>
<GradientStop Color="#FFA3A3A3"/>
</LinearGradientBrush>
</TextBlock.Background>
</TextBlock>
<TextBlock x:Name="textBlock1" HorizontalAlignment="Left" Margin="434,182,0,0" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Top" RenderTransformOrigin="0.482,0.542" Height="27" Width="178" OpacityMask="White">
<TextBlock.Background>
<RadialGradientBrush>
<GradientStop Color="Black" Offset="0"/>
<GradientStop Color="#FFE0DFDF"/>
</RadialGradientBrush>
</TextBlock.Background>
</TextBlock>
<Label x:Name="label3" Content="Valid Until : " HorizontalAlignment="Left" Margin="346,11,0,0" VerticalAlignment="Top"/>
<CheckBox x:Name="checkBox" Content="Keep old password" HorizontalAlignment="Left" Margin="220,108,0,0" VerticalAlignment="Top"/>
<Button x:Name="button" Content="Apply" HorizontalAlignment="Left" Margin="435,215,0,0" VerticalAlignment="Top" Width="178" Height="29" BorderBrush="White" Background="#FFA6A5A5"/>
<ListBox x:Name="listBox" HorizontalAlignment="Left" Height="125" Margin="95,32,0,-0.2" VerticalAlignment="Top" Width="120" Visibility="Hidden" IsSynchronizedWithCurrentItem="True"/>
<TextBox x:Name="textBox" HorizontalAlignment="Left" Height="23" Margin="95,14,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" />
</Grid>
</TabItem>
<TabItem Header="Re-Activate Admin Account">
<Grid Background="#FFE5E5E5">
<Label x:Name="label4" Content="User : " HorizontalAlignment="Left" Margin="85,10,0,0" VerticalAlignment="Top"/>
<TextBox x:Name="textBox3" HorizontalAlignment="Left" Height="23" Margin="133,13,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/>
<Calendar HorizontalAlignment="Left" Margin="420,10,0,0" VerticalAlignment="Top" Height="168" Width="188"/>
<Button x:Name="button1" Content="Button" HorizontalAlignment="Left" Margin="420,214,0,0" VerticalAlignment="Top" Width="193" Height="29"/>
</Grid>
</TabItem>
<TabItem Content="New User" Header="New User"/>
<TabItem Header="Unlock User"/>
<TabItem Header="New Extern User">
<Grid Background="#FFE5E5E5">
<TextBox x:Name="textBox4" HorizontalAlignment="Left" Height="23" Margin="111,14,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/>
<TextBox x:Name="textBox5" HorizontalAlignment="Left" Height="23" Margin="111,49,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/>
<TextBox x:Name="textBox6" HorizontalAlignment="Left" Height="23" Margin="111,88,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/>
<TextBox x:Name="textBox7" HorizontalAlignment="Left" Height="23" Margin="111,127,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/>
<TextBox x:Name="textBox8" HorizontalAlignment="Left" Height="23" Margin="111,167,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/>
<Label x:Name="label5" Content="Firstname :" HorizontalAlignment="Left" Margin="36,10,0,0" VerticalAlignment="Top"/>
<Label x:Name="label6" Content="Lastname :" HorizontalAlignment="Left" Margin="36,45,0,0" VerticalAlignment="Top"/>
<Label x:Name="label7" Content="E-Mail-Address :" HorizontalAlignment="Left" Margin="6,85,0,0" VerticalAlignment="Top"/>
<Label x:Name="label8" Content="Manager :" HorizontalAlignment="Left" Margin="39,124,0,0" VerticalAlignment="Top"/>
<Label x:Name="label9" Content="Ticketnumber :" HorizontalAlignment="Left" Margin="15,163,0,0" VerticalAlignment="Top"/>
<TextBlock x:Name="textBlock2" HorizontalAlignment="Left" Margin="295,14,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Height="175" Width="318" Background="#FF323131" Foreground="White" Cursor="Wait"/>
<Button x:Name="button2" Content="Button" HorizontalAlignment="Left" Margin="503,212,0,0" VerticalAlignment="Top" Width="110" Height="31"/>
</Grid>
</TabItem>
</TabControl>
</Grid>
</Window>
"#
$inputXML = $inputXML -replace 'mc:Ignorable="d"','' -replace "x:N",'N' -replace '^<Win.*', '<Window'
[void][System.Reflection.Assembly]::LoadWithPartialName('presentationframework')
[xml]$XAML = $inputXML
#Read XAML
$reader=(New-Object System.Xml.XmlNodeReader $xaml)
try{
$Form=[Windows.Markup.XamlReader]::Load( $reader )
}
catch{
Write-Warning "Unable to parse XML, with error: $($Error[0])`n Ensure that there are NO SelectionChanged or TextChanged properties in your textboxes (PowerShell cannot process them)"
throw
}
#===========================================================================
# Load XAML Objects In PowerShell
#===========================================================================
$xaml.SelectNodes("//*[#Name]") | %{"trying item $($_.Name)";
try {Set-Variable -Name "WPF$($_.Name)" -Value $Form.FindName($_.Name) -ErrorAction Stop}
catch{throw}
}
Function Get-FormVariables{
if ($global:ReadmeDisplay -ne $true){Write-host "If you need to reference this display again, run Get-FormVariables" -ForegroundColor Yellow;$global:ReadmeDisplay=$true}
write-host "Found the following interactable elements from our form" -ForegroundColor Cyan
get-variable WPF*
}
Get-FormVariables
#===========================================================================
# Use this space to add code to the various form elements in your GUI
#===========================================================================
#setzt die Variablen auf bestimmte Objekte, wodurch das Verändern der Objekte sehr flexibel ist
$OutputBox = $Form.FindName('textBlock')
$InputBox = $Form.FindName('textBox')
$ListBox = $Form.FindName('listBox')
#Eventhandler
$InputBox.Add_TextChanged({
$input = $InputBox.Text
if($input.length -gt 3){
$ListBox.Visibility ="Visible"
$input = "*" + $input + "*"
$user = #(Get-ADUser -Filter ' Name -like $input ' | Select -ExpandProperty Name)
#debug $OutputBox.Text = ($user | ForEach {"{0}`r" -f $_})
$ListBox.itemsSource = $user
---> Here should be the eventhandler for clicking an item in the listbox <---
# $listuser = Get-ADUser -Filter ' Name -like $ListBox.SelectedItem '
# $OutputBox.Text = $ListBox.SelectedItem
}
})
$Form.ShowDialog()
The answer:
$ListBox.add_SelectionChanged({$OutputBox.Text = $ListBox.SelectedItem})
Personally I prefer creating special function with events and call it before $Form.ShowDialog(). Add as much events as you need. Example:
function event_handler
{
$textbox_name.add_TextChanged({$textbox_Login.Text = Construct-Login $textbox_name.Text $textbox_LastName.Text})
}
In this example when you type something to the textbox textbox_name, function Construct-Login is invoked and result is written to another textbox.
By the way, you don't need extra
$OutputBox = $Form.FindName('textBlock')
$ListBox = $Form.FindName('listBox')
since $xaml.SelectNodes does the thing for you. Just make sure you have unique names for all controls at your form.
Related
Please can you help me?
The code makes this output error:
Unable to load Windows.Markup.XamlReader
This code is made by Microsoft Visual Studio - Project WPF APP
[void][System.Reflection.Assembly]::LoadWithPartialName('presentationframework')
[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"
xmlns:local="clr-namespace:WpfApp2"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Label Name="label1" Content="Label" HorizontalAlignment="Left" Margin="222,102,0,0" VerticalAlignment="Top" Width="92"/>
<Label Name="label2" Content="Label" HorizontalAlignment="Left" Margin="222,177,0,0" VerticalAlignment="Top" Width="92"/>
<Label Name="label3" Content="Label" HorizontalAlignment="Left" Margin="222,246,0,0" VerticalAlignment="Top" Width="92"/>
<TextBox Name="text1" HorizontalAlignment="Left" Margin="369,110,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120" TextChanged="text1_TextChanged_1"/>
<TextBox Name="text2" HorizontalAlignment="Left" Margin="369,185,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120" RenderTransformOrigin="0.483,4.29"/>
<TextBox Name="text3" HorizontalAlignment="Left" Margin="369,254,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120" RenderTransformOrigin="0.483,4.29"/>
<Button Name="button1" Content="Button" HorizontalAlignment="Left" Margin="572,168,0,0" VerticalAlignment="Top" Width="131" Height="46"/>
</Grid>
</Window>
"#
#Read XAML
$reader=(New-Object System.Xml.XmlNodeReader $xaml)
try{$Form=[Windows.Markup.XamlReader]::Load( $reader )}
catch{Write-Host "Unable to load Windows.Markup.XamlReader"; exit}
# Store Form Objects In PowerShell
$xaml.SelectNodes("//*[#Name]") | ForEach-Object {Set-Variable -Name ($_.Name) -Value $Form.FindName($_.Name)}
#Show Form
$Form.ShowDialog() | out-null
I create a GUI with Visual Studio and import the XAML code in Powershell and i have a problem to display in textbox a value from one of 5 combobox selected item.
I learn by myself and i really love it but i dont have the good method for debbug my code alone,
anybody can have a time and a knowledge for help me please ?
I want to display in textbox ($TxtBox) the selected item (or value) from CboPL or CboTG or CboSB....
with powershell.
This is my XAML code beetwen here string in powershell :
<Window x:Name="Main" x:Class="Printers_Ordi.MainWindow"
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"
xmlns:local="clr-namespace:Printers_Ordi"
mc:Ignorable="d"
Title="Printers-Ordi" Height="450" Width="728.471">
<Grid x:Name="Wall">
<Grid.Background>
<ImageBrush ImageSource="C:/Users/admsb160365/Desktop/scripts Shell/Imprimantes GHT/Wall.png"/>
</Grid.Background>
<Label x:Name="LabelTitre" Content="Printers-Ordi" HorizontalAlignment="Left" Margin="74,25,0,0" VerticalAlignment="Top" FontFamily="Yu Gothic UI Semibold" FontSize="24" RenderTransformOrigin="0.503,0.76" Height="42" Width="164" Foreground="#FF1346CD"/>
<ComboBox x:Name="CboComputer" HorizontalAlignment="Left" Margin="74,82,0,0" VerticalAlignment="Top" Width="164" FontSize="16" Height="31" IsEditable="True" IsReadOnly="True" Text="Ordinateur"/>
<ComboBox x:Name="CboSites" HorizontalAlignment="Left" Margin="74,118,0,0" VerticalAlignment="Top" Width="164" Height="31" FontSize="16" IsEditable="True" IsReadOnly="True" Text="Sites">
<ComboBox x:Name="CboPL" HorizontalAlignment="Left" VerticalAlignment="Top" Width="154" FontSize="16" IsEditable="True" IsReadOnly="True" Text="Paimpol"/>
<ComboBox x:Name="CboGP" HorizontalAlignment="Left" VerticalAlignment="Top" Width="154" FontSize="16" IsEditable="True" IsReadOnly="True" Text="Guingamp"/>
<ComboBox x:Name="CboSB" HorizontalAlignment="Left" VerticalAlignment="Top" Width="154" FontSize="16" IsEditable="True" IsReadOnly="True" Text="SaintBrieuc"/>
<ComboBox x:Name="CboLN" HorizontalAlignment="Left" VerticalAlignment="Top" Width="154" FontSize="16" IsEditable="True" IsReadOnly="True" Text="Lannion"/>
<ComboBox x:Name="CboTG" HorizontalAlignment="Left" VerticalAlignment="Top" Width="154" FontSize="16" IsEditable="True" IsReadOnly="True" Text="Treguier"/>
</ComboBox>
Thanks by advance for your patience and support ;-)
Continuing from my comments. There are a few ways to deal with your use case. Here is a simple example using Winform. Ultimately, it's still collecting/assigning text from one element(s)/or code results to another.
Add-Type -AssemblyName System.Drawing
$ComboBox = New-Object System.Windows.Forms.ComboBox
$ComboBox.Location = New-Object System.Drawing.Point(10,10)
$ComboBox.Items.AddRange(#('One','Two'))
$RichTextBox = New-Object System.Windows.Forms.RichTextBox
$RichTextBox.Location = New-Object System.Drawing.Point(10,40)
$Form = New-Object System.Windows.Forms.Form
$Form.Controls.Add($ComboBox)
$Form.Controls.Add($RichTextBox)
$ComboBox.Add_TextChanged({
switch($ComboBox.Text){
'One' {$RichTextBox.Text = 'This is one'}
'Two' {$RichTextBox.Text = 'This is two'}
}
})
$Form.ShowDialog()
An example using WPF
[void][System.Reflection.Assembly]::LoadWithPartialName('presentationframework')
[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="PowerShell Form" Height="310" Width="350" ResizeMode="NoResize">
<Grid Margin="0,0,0,0">
<GroupBox Header="General" HorizontalAlignment="Left" Height="225" Margin="10,10,0,0" VerticalAlignment="Top" Width="320">
<Grid HorizontalAlignment="Left" Height="206" Margin="0,0,0,0" VerticalAlignment="Top" Width="320">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="60*"/>
<ColumnDefinition Width="250*"/>
</Grid.ColumnDefinitions>
<Label Content="Field #1:" HorizontalAlignment="Left" Margin="0,7,0,0" VerticalAlignment="Top" Height="26" Width="93"/>
<Label Content="Field #2:" HorizontalAlignment="Left" Margin="0,35,0,0" VerticalAlignment="Top" Height="26" Width="93"/>
<Label Content="Field #3:" HorizontalAlignment="Left" Margin="0,65,0,0" VerticalAlignment="Top" Height="26" Width="93"/>
<TextBox Name="f1" HorizontalAlignment="Left" Height="23" Margin="10,10,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="229" Grid.Column="1"/>
<ComboBox Name="f2" HorizontalAlignment="Left" Height="23" Margin="10,38,0,0" VerticalAlignment="Top" Width="229" Grid.Column="1">
<ListBoxItem>Test 1</ListBoxItem>
<ListBoxItem>Test 2</ListBoxItem>
<ListBoxItem>Test 3</ListBoxItem>
</ComboBox>
<TextBox Name="f3" HorizontalAlignment="Left" Height="23" Margin="10,66,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="229" Grid.Column="1"/>
</Grid>
</GroupBox>
<Button Name="Clear" Content="Clear Form" HorizontalAlignment="Left" Margin="10,240,0,0" VerticalAlignment="Top" Width="90" Height="30" RenderTransformOrigin="0.522,0.733"/>
<Button Name="Submit" Content="Submit" Margin="234,240,12,0" VerticalAlignment="Top" Height="30"/>
</Grid>
</Window>
'#
$reader = (New-Object System.Xml.XmlNodeReader $xaml)
try{$Form = [Windows.Markup.XamlReader]::Load( $reader )}
catch
{
Write-Host 'Unable to load Windows.Markup.XamlReader.'
break
}
$xaml.SelectNodes('//*[#Name]') |
ForEach-Object {Set-Variable -Name ($_.Name) -Value $Form.FindName($_.Name)}
$Form.Add_Loaded({
if (Test-Path -Path '.\ComboBox.selection')
{
$cbSelection = Get-Content '.\ComboBox.selection'
[int]$cbSelectionInt = -1
[void][int]::TryParse($cbSelection,[ref]$cbSelectionInt)
if ($cbSelectionInt -ge 0)
{$f2.SelectedIndex = $cbSelectionInt}
}
})
$Clear.Add_Click({
$fields = #('f1','f2','f3')
foreach ($field in $fields)
{
$control = $Form.FindName($field)
switch ($control.GetType()) {
'System.Windows.Controls.TextBox' {$control.Clear()}
'System.Windows.Controls.ComboBox' {$control.SelectedIndex = -1}
DEFAULT {'unknown control'}
}
}
})
$f2.add_SelectionChanged({
param($sender,$args)
$f3.Text = ($($sender.SelectedValue) -replace '.*:\s+')
})
$Form.ShowDialog()
I'm trying to make a remote copy tool, which works fine in the console but I'm having trouble creating the GUI for it.
When I populate my Listbox with the list of files to copy they just don't display as intended...
My problem is in the ChooseFiles function
#xaml Code
$inputXML = #"
<Window x:Class="RemoteCopy.MainWindow"
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"
xmlns:local="clr-namespace:RemoteCopy"
mc:Ignorable="d"
Title="Remote Copy" Height="556.841" Width="800">
<Grid>
<Label Content="Remote Computer's IP:" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top"/>
<TextBox x:Name="RemoteIPTextbox" HorizontalAlignment="Left" Height="20" Margin="238,16,0,0" TextWrapping="Wrap" Text="IP address" VerticalAlignment="Top" Width="128"/>
<Label Content="Username: " HorizontalAlignment="Left" Height="26" Margin="10,40,0,0" VerticalAlignment="Top" Width="131"/>
<Label Content="Password: " HorizontalAlignment="Left" Height="26" Margin="10,70,0,0" VerticalAlignment="Top" Width="131"/>
<TextBox x:Name="UsernameTextbox" HorizontalAlignment="Left" Height="20" Margin="238,46,0,0" TextWrapping="Wrap" Text="Username" VerticalAlignment="Top" Width="128"/>
<Button x:Name="CheckConnectionButton" Content="Check Connection" HorizontalAlignment="Left" Margin="389,46,0,0" VerticalAlignment="Top" Width="107" Height="20"/>
<Button x:Name="ChooseFilesButton" Content="Choose Files" HorizontalAlignment="Left" Height="80" Margin="535,16,0,0" VerticalAlignment="Top" Width="122"/>
<ListView x:Name="FilesListView" HorizontalAlignment="Left" Height="234" Margin="33,128,0,0" VerticalAlignment="Top" Width="720">
<ListView.View>
<GridView>
<GridViewColumn Header="File"/>
<GridViewColumn Header="Size"/>
</GridView>
</ListView.View>
</ListView>
<Button x:Name="StartCopyButton" Content="Start Copy" HorizontalAlignment="Left" Height="24" Margin="33,374,0,0" VerticalAlignment="Top" Width="720"/>
<ProgressBar x:Name="ProgressBar" HorizontalAlignment="Left" Height="20" Margin="113,418,0,0" VerticalAlignment="Top" Width="572"/>
<Label Content="Progress:" HorizontalAlignment="Left" Height="28" Margin="33,418,0,0" VerticalAlignment="Top" Width="67"/>
<Label Content="100%" HorizontalAlignment="Left" Height="28" Margin="714,418,0,0" VerticalAlignment="Top" Width="39"/>
<PasswordBox x:Name="Passwordbox" HorizontalAlignment="Left" Margin="238,78,0,0" VerticalAlignment="Top" Width="128"/>
<Button x:Name="ExitButton" Content="Exit" HorizontalAlignment="Left" Height="21" Margin="283,455,0,0" VerticalAlignment="Top" Width="213"/>
</Grid>
</Window>
"#
$inputXML = $inputXML -replace 'mc:Ignorable="d"','' -replace "x:N",'N' -replace '^<Win.*', '<Window'
[void][System.Reflection.Assembly]::LoadWithPartialName('presentationframework')
[xml]$XAML = $inputXML
#Read XAML
$reader=(New-Object System.Xml.XmlNodeReader $xaml)
try{
$Form=[Windows.Markup.XamlReader]::Load( $reader )
}
catch{
Write-Warning "Unable to parse XML, with error: $($Error[0])`n Ensure that there are NO SelectionChanged or TextChanged properties in your textboxes (PowerShell cannot process them)"
throw
}
#===========================================================================
# Load XAML Objects In PowerShell
#===========================================================================
$xaml.SelectNodes("//*[#Name]") | %{"trying item $($_.Name)";
try {Set-Variable -Name "WPF$($_.Name)" -Value $Form.FindName($_.Name) -ErrorAction Stop}
catch{throw}
}
Function Get-FormVariables{
if ($global:ReadmeDisplay -ne $true){Write-host "If you need to reference this display again, run Get-FormVariables" -ForegroundColor Yellow;$global:ReadmeDisplay=$true}
write-host "Found the following interactable elements from our form" -ForegroundColor Cyan
get-variable WPF*
}
Get-FormVariables
#===========================================================================
# Use this space to add code to the various form elements in your GUI
#===========================================================================
#my test folder
c:
Set-Location c:\temp
function DisplayInBytes($num)
#reference: https://stackoverflow.com/questions/24616806/powershell-display-files-size-as-kb-mb-or-gb
{
$suffix = "B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"
$index = 0
while ($num -gt 1kb)
{
$num = $num / 1kb
$index++
}
"{0:N1} {1}" -f $num, $suffix[$index]
}
function ChooseFiles
{
$WPFFilesListView.Clear()
$filesToCopy = Get-Files
$filesToCopy.FileNames | ForEach-Object {
$currentfilesize = (Get-Item $_).Length
$currentfilesize = DisplayInBytes -num $currentfilesize
$row = New-Object System.Windows.Forms.ListViewItem($_)
[void]$row.SubItems.Add("$currentfilesize")
[void]$WPFFilesListView.Items.Add($row)
}
}
Function Get-Files($initialDirectory="")
#Reference to https://stackoverflow.com/questions/15885132/file-folder-chooser-dialog-from-a-windows-batch-script
{
[System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms")|Out-Null
$myFile = new-object Windows.Forms.OpenFileDialog
$myFile.InitialDirectory = Get-Location
$myFile.Filter = "Text Files (*.txt)|*.txt|Powershell Script Files (*.ps1)|*.ps1|Batch Files (*.bat)|*.bat|All Files (*.*)|*.*"
$myFile.ShowHelp = $true
$myFile.Multiselect = $true
[void]$myfile.ShowDialog()
if ($myFile.Multiselect) { $myFile.FileNames } else { $myFile.FileName }
return $myFile
}
$WPFExitButton.Add_Click({$form.close()})
$WPFChooseFilesButton.Add_Click({ChooseFiles})
$Form.ShowDialog() | out-null
The Function to Choose my Files and Populate my Listbox is this one:
function ChooseFiles
{
$WPFFilesListView.Clear()
$filesToCopy = Get-Files
$filesToCopy.FileNames | ForEach-Object {
$currentfilesize = (Get-Item $_).Length
$currentfilesize = DisplayInBytes -num $currentfilesize
$row = New-Object System.Windows.Forms.ListViewItem($_)
[void]$row.SubItems.Add("$currentfilesize")
[void]$WPFFilesListView.Items.Add($row)
}
}
But my Result looks like this:
I intended to have the Filename and Filesize displayed,
If I test the Variables they work
Write-host $_
write-host $currentfilesize
One in each column
You need to change two things to fix the display:
Add a DisplayMemberBinding to the ListView
<ListView x:Name="FilesListView" HorizontalAlignment="Left" Height="234" Margin="33,128,0,0" VerticalAlignment="Top" Width="720">
<ListView.View>
<GridView>
<GridViewColumn Header="File" DisplayMemberBinding="{Binding File}"/>
<GridViewColumn Header="Size" DisplayMemberBinding="{Binding Size}"/>
</GridView>
</ListView.View>
</ListView>
Pass a pscustomobject with the specified binding properties to the ListView
function ChooseFiles
{
$WPFFilesListView.Clear()
$filesToCopy = Get-Files
$filesToCopy.FileNames | ForEach-Object {
$currentfilesize = (Get-Item $_).Length
$currentfilesize = DisplayInBytes -num $currentfilesize
$WPFFilesListView.Items.Add([pscustomobject]#{File=$_;Size=$currentfilesize})
}
}
I have been building GUI's for a while in powershell with XAML. Everything has worked fine until I attempted to bring in ComboBox. Then powershell no longer accepts it.
I have built the XAML in Visual Studio and it works in Design view. Every website I go to tells me this is the right XAML code. The error occurs with the code
$reader=(New-Object System.Xml.XmlNodeReader $xaml)
try{$DiagForm=[Windows.Markup.XamlReader]::Load( $reader )}
Here is the sample I am working with. If you take out the ComboBox segment, it works perfectly fine.
function Diag {
[void][System.Reflection.Assembly]::LoadWithPartialName('presentationframework')
[xml]$XAML = #'
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Tool" Height="500" Width="300" WindowStartupLocation="CenterScreen" WindowStyle='SingleBorderWindow' ResizeMode='CanMinimize'>
<Grid>
<TextBox HorizontalAlignment="Center" Height="23" TextWrapping="Wrap" Text="Diagnostics" VerticalAlignment="Top" Width="300" Margin="0,-1,-0.2,0" TextAlignment="Center" Foreground="White" Background="#21C500"/>
<Label Content="Report" HorizontalContentAlignment="Center" HorizontalAlignment="Left" Margin="90,27,0,0" VerticalAlignment="Top" Width="120"/>
<ComboBox HorizontalAlignment="Left" Margin="90,60,0,0" VerticalAlignment="Top" Width="120">
<ComboBoxItem MouseMove="OnHover" Name="Period1" IsSelected="True">Last 24hr</ComboBoxItem>
<ComboBoxItem MouseMove="OnHover" Name="Period2" IsSelected="False">Last Week</ComboBoxItem>
<ComboBoxItem MouseMove="OnHover" Name="Period3" IsSelected="False">Last Month</ComboBoxItem>
</ComboBox>
<Label Content="Critical" HorizontalAlignment="Left" Margin="46,115,0,0" VerticalAlignment="Top"/>
<TextBox HorizontalAlignment="Left" Height="23" Margin="124,115,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120"/>
<Label Content="Warnings" HorizontalAlignment="Left" Margin="46,143,0,0" VerticalAlignment="Top"/>
<TextBox HorizontalAlignment="Left" Height="23" Margin="124,143,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120"/>
</Grid>
</Window>
'#
#Read XAML
$reader=(New-Object System.Xml.XmlNodeReader $xaml)
try{$DiagForm=[Windows.Markup.XamlReader]::Load( $reader )}
catch{Write-Host "Unable to load Windows.Markup.XamlReader. Some possible causes for this problem include: .NET Framework is missing PowerShell must be launched with PowerShell -sta, invalid XAML code was encountered."; exit}
$xaml.SelectNodes("//*[#Name]") | %{Set-Variable -Name ($_.Name) -Value $DiagForm.FindName($_.Name)}
$DiagForm.ShowDialog() | out-null
}
Diag
If you examine the exception that is being caught, you'll see the following error message:
Failed to create a 'MouseMove' from the text 'OnHover'.
Indeed, if you remove the MouseMove="OnHover" attributes from your XAML, the problem goes away.
Need advice on adding a text in let's say Text_Status after hitting a button.
How can I also automatically continue the command after a restart to let's say Button_clearTPM, then going to Button_enableTPM, then going to Button_initializeTPM?
Here is my XAML:
[xml]$xaml = #'
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="TPM Script" Height="482" Width="479" Background="White">
<Grid Height="375" Width="382">
<Button Content="Clear TPM" Height="55" HorizontalAlignment="Left" Margin="230,30,0,0" Name="Button_clearTPM" VerticalAlignment="Top" Width="140"/>
<Button Content="Enable TPM" Height="55" HorizontalAlignment="Left" Margin="230,0,0,220" Name="Button_enableTPM" VerticalAlignment="Bottom" Width="140"/>
<Button Content="Initialize TPM" Height="55" HorizontalAlignment="Left" Margin="230,169,0,0" Name="Button_initializeTPM" VerticalAlignment="Top" Width="140"/>
<Label Content="Enter Workstation ID: " Height="23" HorizontalAlignment="Left" Margin="31,45,0,0" Name="Label_1" VerticalAlignment="Top" Width="133"/>
<TextBox Height="38" HorizontalAlignment="Left" Margin="31,74,0,0" Name="Text_WSID" VerticalAlignment="Top" Width="171" />
<TextBox Height="114" HorizontalAlignment="Left" Margin="31,241,0,0" Name="Text_Status" VerticalAlignment="Top" Width="329" />
</Grid>
</Window>
'#
[void][System.Reflection.Assembly]::LoadWithPartialName('presentationframework')
$reader=(New-Object System.Xml.XmlNodeReader $xaml)
try
{
$Form=[Windows.Markup.XamlReader]::Load( $reader )
}
catch
{
Write-Host "Unable to load Windows.Markup.XamlReader. Some possible causes for this problem include: .NET Framework is missing PowerShell must be launched with PowerShell -sta, invalid XAML code was encountered."t
}
cls
#First Button
$clearTPM = $Form.FindName('Button_clearTPM')
$clearTPM.Add_Click({ Write-Host "Clear TPM clicked" -ForegroundColor Cyan})
#Second Button
$enableTPM = $Form.FindName('Button_enableTPM')
$enableTPM.Add_Click({ Write-Host "Enable TPM clicked" -ForegroundColor Cyan})
#Third Button
$initializeTPM = $Form.FindName('Button_initializeTPM')
$initializeTPM.Add_Click({ Write-Host "Initialize TPM clicked" -ForegroundColor Cyan})
$Form.ShowDialog() | out-null
##Possible Commands
#Clear-Tpm
#Enable-TpmAutoProvisioning (Export C:Notbackedup)
#Initialize-Tpm
The problem is your script doesn't know what your label is.
So you have to make it accessible by making it into a variable.
Then, you can assign whatever text you want via .Content.
So :
[xml]$xaml = #'
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="TPM Script" Height="482" Width="479" Background="White">
<Grid Height="375" Width="382">
<Button Content="Clear TPM" Height="55" HorizontalAlignment="Left" Margin="230,30,0,0" Name="Button_clearTPM" VerticalAlignment="Top" Width="140"/>
<Button Content="Enable TPM" Height="55" HorizontalAlignment="Left" Margin="230,0,0,220" Name="Button_enableTPM" VerticalAlignment="Bottom" Width="140"/>
<Button Content="Initialize TPM" Height="55" HorizontalAlignment="Left" Margin="230,169,0,0" Name="Button_initializeTPM" VerticalAlignment="Top" Width="140"/>
<Label Content="Enter Workstation ID: " Height="23" HorizontalAlignment="Left" Margin="31,45,0,0" Name="Label_1" VerticalAlignment="Top" Width="133"/>
<TextBox Height="38" HorizontalAlignment="Left" Margin="31,74,0,0" Name="Text_WSID" VerticalAlignment="Top" Width="171" />
<TextBox Height="114" HorizontalAlignment="Left" Margin="31,241,0,0" Name="Text_Status" VerticalAlignment="Top" Width="329" />
</Grid>
</Window>
'#
[void][System.Reflection.Assembly]::LoadWithPartialName('presentationframework')
$reader=(New-Object System.Xml.XmlNodeReader $xaml)
try
{
$Form=[Windows.Markup.XamlReader]::Load( $reader )
}
catch
{
Write-Host "Unable to load Windows.Markup.XamlReader. Some possible causes for this problem include: .NET Framework is missing PowerShell must be launched with PowerShell -sta, invalid XAML code was encountered."t
}
## THIS IS WHERE MAGIC HAPPENS
$xaml.SelectNodes("//*[#Name]") | %{Set-Variable -Name "$($_.Name)" -Value $Form.FindName($_.Name)} # find all names and make them accessible via a variable
#First Button
$clearTPM = $Form.FindName('Button_clearTPM')
$clearTPM.Add_Click({
Write-Host "Clear TPM clicked" -ForegroundColor Cyan
$label_1.content = "Clear TPM clicked"
})
#Second Button
$enableTPM = $Form.FindName('Button_enableTPM')
$enableTPM.Add_Click({ Write-Host "Enable TPM clicked" -ForegroundColor Cyan})
#Third Button
$initializeTPM = $Form.FindName('Button_initializeTPM')
$initializeTPM.Add_Click({ Write-Host "Initialize TPM clicked" -ForegroundColor Cyan})
$Form.ShowDialog() | out-null
##Possible Commands
#Clear-Tpm
#Enable-TpmAutoProvisioning (Export C:Notbackedup)
#Initialize-Tpm