Last active
September 2, 2022 17:20
-
-
Save BananaAcid/d0ea1eea1eb0d3b98f4ebd525df67622 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# (c) Nabil Redmann 2019 | |
# based on https://stackoverflow.com/a/52416973/1644202 | |
function LoadXamlFile | |
{ | |
Param | |
( | |
[Parameter(Mandatory=$true)] $xamlFile | |
) | |
$xamlString = Get-Content -Path $xamlFile | |
$Form,$Elements = LoadXamString($xamlString) | |
return $Form, $Elements | |
} | |
function LoadXamString | |
{ | |
Param | |
( | |
[Parameter(Mandatory=$true)] $xamlString | |
) | |
Add-Type -AssemblyName PresentationFramework,PresentationCore,WindowsBase | |
If (!$knownEvents) { $knownEvents = @( | |
# Some major events. There are way more. | |
# Window | |
"Initialized", "Loaded", "Unloaded", "Activated", "Closed", "Closing", "GotFocus", "LostFocus", "SizeChanged", | |
# Checkbox, Buttons etc | |
"Click", "Checked", "MouseDoubleClick", "MouseEnter", "MouseLeave", "MouseDown", "MouseUp", "MouseLeftButtonDown", "MouseLeftButtonUp", "MouseRightButtonDown", "MouseRightButtonUp", "MouseMove", "MouseWheel", | |
# Text | |
"KeyDown", "KeyUp", "PreviewKeyDown", "PreviewKeyUp" | |
) } | |
# store window class | |
$windowClass = [Regex]::Match($xamlString, '^<Window[^>]*x:Class="([^"]*)').Captures.Groups[1].Value | |
#=========================================================================== | |
# fix XAML markup for powershell | |
#=========================================================================== | |
$xamlString = $xamlString -replace 'mc:Ignorable="d"','' -replace "x:N",'N' -replace '^<Win.*', '<Window' -replace "x:Bind", "Binding" | |
[xml]$XAML = $xamlString | |
#=========================================================================== | |
# storing events | |
#=========================================================================== | |
$eventElements = @() | |
Foreach ($event in $knownEvents) { | |
Foreach ($node in $XAML.SelectNodes("//*[@$event]")) { | |
If (!$node.Name) { $node.AddAttribute("Name", "el_$(Get-Random)") } | |
$eventElements += @{ | |
e = $node | |
ev = $event | |
fn = $node.$event | |
name = $node.Name | |
} | |
$node.RemoveAttribute($event) | |
} | |
} | |
#=========================================================================== | |
#Read XAML | |
#=========================================================================== | |
$reader = (New-Object System.Xml.XmlNodeReader $XAML) | |
try{ $Form = [Windows.Markup.XamlReader]::Load($reader) } | |
catch [System.Management.Automation.MethodInvocationException] { | |
Write-Warning "We ran into a problem with the XAML code. Check the syntax for this control..." | |
write-host $error[0].Exception.Message -ForegroundColor Red | |
} | |
catch{#if it broke some other way | |
Write-Host "Unable to load Windows.Markup.XamlReader. Double-check syntax and ensure .net is installed." | |
} | |
#=========================================================================== | |
# attaching click handlers | |
#=========================================================================== | |
Write-Host "Form class: $windowClass " | |
Foreach ($evData in $eventElements) { | |
$fnName = $evData.fn | |
if ($windowClass) { | |
$fnName = "$windowClass.$fnName" | |
} | |
Write-Host "Linking event $($evData.ev) on element $($evData.name) -> function $fnName()" | |
$fns = Get-ChildItem function: | Where-Object { $_.Name -like $fnName } # function namespace.windowclassname.function_name($Sender, $EventArgs) | |
If (!$fns.Count) { | |
Write-Host ".. handler function does not exist: $fnName(`$Sender,`$EventArgs)" -ForegroundColor Red | |
} | |
else { | |
Invoke-Expression ('$Form.FindName($evData.name).Add_' + $evData.ev + '( $fns[0].ScriptBlock )') | |
} | |
} | |
#=========================================================================== | |
# Store named elements to be acessable through $Elements | |
#=========================================================================== | |
$Elements = @{} | |
$xaml.SelectNodes("//*[@Name]") | %{ $Elements[$_.Name] = $Form.FindName($_.Name) } | |
$Elements["_Window"] = $Form | |
return $Elements, $Elements._Window | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<Window x:Class="WpfApp2.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:WpfApp2" | |
mc:Ignorable="d" | |
Title="MainWindow" Height="450" Width="800"> | |
<Grid> | |
<ListView SelectionMode="Multiple" x:Name="lvApps" Height="371" VerticalAlignment="Top"> | |
<ListView.ItemTemplate> | |
<DataTemplate> | |
<StackPanel Orientation="Horizontal" Height="64" AutomationProperties.Name="{Binding Name}"> | |
<Ellipse Height="48" Width="48" VerticalAlignment="Center"> | |
<Ellipse.Fill> | |
<ImageBrush ImageSource="{Binding ButtonImage}"/> | |
</Ellipse.Fill> | |
</Ellipse> | |
<StackPanel Orientation="Vertical" VerticalAlignment="Center" Margin="12,0,0,0"> | |
<TextBlock Text="{Binding Name}" /> | |
<TextBlock Text="{Binding Description}" /> | |
</StackPanel> | |
</StackPanel> | |
</DataTemplate> | |
</ListView.ItemTemplate> | |
</ListView> | |
<Button x:Name="doInstallAll" Content="install all" Width="75" VerticalAlignment="Center" Click="DoInstallAll_Click" /> | |
</Grid> | |
</Window> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
start powershell.exe -ExecutionPolicy Bypass -Command .\start.ps1;Read-Host "Press Enter to continue ..." |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# import logic | |
. .\gui.framework.ps1 | |
# define handler to be auto attached - window.class + ckick-handler --> before loading the GUI ! | |
function WpfApp2.MainWindow.DoInstallAll_Click($Sender, $EventArgs) { | |
#write-host $Sender,$EventArgs | |
Write-Host "WORKS !"$Elements.lvApps.Items.Count # $Elements will be available at the time of execution | |
} | |
# load main gui | |
$Elements, $Form = LoadXamlFile .\gui.xaml | |
# add some element | |
$Elements.lvApps.AddChild([pscustomobject]@{Name='Ben';Description="sdsd 343"}) | |
# show ui | |
$Form.ShowDialog() | out-null | |
# add handler manually (alternative) | |
$Elements.doInstall.Add_Click({ | |
Write-Host "!" | |
}) | |
# | |
# Use `Invoke-All` to start work intensive stuff in a seperate thread to not block the UI | |
# | |
. .\z.helper.ps1 | |
$return = Start-Await-Job { | |
Write-Host "doing prog.." | |
sleep 3 | |
return "..done" | |
} | |
Write-Host $return |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# await a job | |
Add-Type -AssemblyName System.Windows.Forms | |
Function Await-Job { | |
Param | |
( | |
[Parameter(Mandatory=$true)] $job | |
) | |
while ($job.state -eq 'Running') { | |
[System.Windows.Forms.Application]::DoEvents() # keep form responsive | |
} | |
# will wait on job | |
#$consume = Wait-Job $job | |
# Captures and throws any exception in the job output -> '-ErrorAction stop' --- otherwise returns result | |
return Receive-Job $job -ErrorAction Continue | |
} | |
# start and await a job | |
Function Start-Await-Job { | |
Param | |
( | |
[Parameter(Mandatory=$true)] $scriptBlock | |
) | |
$job = Start-Job -ScriptBlock $scriptBlock | |
return Await-Job $job | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment