classes/ViewModel.Class.ps1
Class RunScriptBlockExtension : MarkupExtension { Hidden Static [PropertyInfo] $SingleWorkerProperty Hidden Static [MethodInfo] $AttachToRootItemMethod Hidden Static [MethodInfo] $RawValueMethod [PropertyPath] $Path # The extension uses private API to parse a property path. # This static constructor fetches the pieces using reflection. Static RunScriptBlockExtension() { # A PropertyPath uses an internal type called PropertyPathWorker to do the parsing. # The worker is exposed through the internal property SingleWorker. [RunScriptBlockExtension]::SingleWorkerProperty = [PropertyPath].GetProperty( 'SingleWorker', [BindingFlags]::NonPublic -bor [BindingFlags]::Instance ) # The worker has a method AttachToRootItem, which is used to give the worker the root # item for the path to resolve. [RunScriptBlockExtension]::AttachToRootItemMethod = [RunScriptBlockExtension]::SingleWorkerProperty.PropertyType.GetMethod( 'AttachToRootItem', [BindingFlags]::NonPublic -bor [BindingFlags]::Instance ) # The worker has another method RawValue, which returns the item the path has been resolved # to relative to the root item. [RunScriptBlockExtension]::RawValueMethod = [RunScriptBlockExtension]::SingleWorkerProperty.PropertyType.GetMethod( 'RawValue', [BindingFlags]::NonPublic -bor [BindingFlags]::Instance, $null, [Type]::EmptyTypes, @() ) } # Constructor that is invoked when the extension is created. # The path given is the property path that should be resolved. # E.g. {ps:RunScriptBlock A.B.C} the path is the string "A.B.C". RunScriptBlockExtension([String] $path) { $this.Path = New-Object PropertyPath $path write-host $($this.path) } # Create an event handler for the given event. [Object] ProvideValue([IServiceProvider] $provider) { # Fetch the service that gives use information about the expected result. [IProvideValueTarget] $provideValueTarget = $provider.GetService([IProvideValueTarget]) # In our case we can assume the extension is only bound to event targets. [EventInfo] $eventInfo = $provideValueTarget.TargetProperty # Create a delegate for the expected event handler, and execute the # HandleEvent method below when it occurs. Return [Delegate]::CreateDelegate( $eventInfo.EventHandlerType, $this, [RunScriptBlockExtension].GetMethod('HandleEvent') ) } # Method executed by the event handler that executes the actual ScriptBlock. Hidden [Void] HandleEvent([Object] $sender, [RoutedEventArgs] $e) { write-host $($this.path | out-string) <# # Get the data context of the sender. This is the root element of the property path. [Object] $dataContext = ($sender -as [FrameworkElement]).DataContext # Fetch the path worker of our path. [Object] $worker = [RunScriptBlockExtension]::SingleWorkerProperty.GetMethod.Invoke($this.Path, @()) # Give the data context to the worker. #[RunScriptBlockExtension]::AttachToRootItemMethod.Invoke($worker, @($dataContext)) # Get the resolved ScriptBlock from the worker. [ScriptBlock] $scriptBlock = [RunScriptBlockExtension]::RawValueMethod.Invoke($worker, @()) $scriptBlock.InvokeReturnAsIs($dataContext, $sender, $e) #> $path2 = "C:\Users\Gaspack\Documents\PowerShell\Modules\MineSweeper\guiscripts\$($this.path.path).ps1" IF (Test-Path $path2) { $action2 = Get-Content -Path $path2 -raw $scriptblock = [scriptblock]::Create($action2) #$scriptBlock.InvokeReturnAsIs($dataContext, $sender, $e) $scriptBlock.Invoke() } ELSE { new-item $path2 -force } } } Class ViewModel : DependencyObject { $Title = "GAT SCRIPT2" $GUIJobs = $viewGUIJobs2 #[System.Collections.ObjectModel.ObservableCollection[Object]]::new() $lvRemoteList = [System.Collections.ObjectModel.ObservableCollection[Object]]::new() Hidden [PropertyChangedEventHandler] $PropertyChanged [Void] add_PropertyChanged([PropertyChangedEventHandler] $propertyChanged) { $this.PropertyChanged = [Delegate]::Combine($this.PropertyChanged, $propertyChanged) } [Void] remove_PropertyChanged([PropertyChangedEventHandler] $propertyChanged) { $this.PropertyChanged = [Delegate]::Remove($this.PropertyChanged, $propertyChanged) } Hidden [Void] NotifyPropertyChanged([String] $propertyName) { If ($this.PropertyChanged -cne $null) { $this.PropertyChanged.Invoke($this, (New-Object PropertyChangedEventArgs $propertyName)) } } [Void] RefreshScriptList($path) { $this.lvRemoteList.Clear() Get-ChildItem -path $path -File -Recurse -Include '*.ps1', '*.xaml', '*.sql' | Select-Object FullName, Name, @{Name = 'DirectoryName'; Expression = { $_.Directory.Name } },BaseName | ForEach-Object {$this.lvRemoteList.Add($_)} } } [ViewModel] $viewModel = New-Object ViewModel |