├── Assembly
├── Courtesy of MDIX project
├── MaterialDesignColors.dll
└── MaterialDesignThemes.Wpf.dll
├── CommonFunctions.ps1
├── CommonTheme.ps1
├── Content of Examples.txt
├── Example.config
├── Example1.ps1
├── Example1.xaml
├── Example11.ps1
├── Example11.xaml
├── Example13.config
├── Example13.ps1
├── Example13.xaml
├── Example15.ps1
├── Example15.xaml
├── Example17.ps1
├── Example17.xaml
├── Example2.ps1
├── Example2.xaml
├── Example3.ps1
├── Example3.xaml
├── Example4.ps1
├── Example4.xaml
├── Example6.ps1
├── Example6.xaml
├── Example7.ps1
├── Example7.xaml
├── Example8.ps1
├── Example8.xaml
├── Example9.ps1
├── Example9.xaml
├── Example9b.ps1
├── Example9b.xaml
├── README.md
├── Resources
└── Images
│ ├── mr_bean.jpg
│ └── mr_bean_tiny.jpg
└── cars.csv
/Assembly/Courtesy of MDIX project:
--------------------------------------------------------------------------------
1 | https://github.com/MaterialDesignInXAML/MaterialDesignInXamlToolkit
2 |
--------------------------------------------------------------------------------
/Assembly/MaterialDesignColors.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DrHalfBaked/PowerShell.MaterialDesign/e53a8b2c2e8e28a7c5c40d15fac4cb78b562d00b/Assembly/MaterialDesignColors.dll
--------------------------------------------------------------------------------
/Assembly/MaterialDesignThemes.Wpf.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DrHalfBaked/PowerShell.MaterialDesign/e53a8b2c2e8e28a7c5c40d15fac4cb78b562d00b/Assembly/MaterialDesignThemes.Wpf.dll
--------------------------------------------------------------------------------
/CommonFunctions.ps1:
--------------------------------------------------------------------------------
1 | ###########
2 | # Learn how to build Material Design based PowerShell apps
3 | #
4 | # Common Functions, Variables and Assemblies
5 | #
6 | # Avi Coren (c)
7 | # Blog - https://www.materialdesignps.com
8 | # Github - https://github.com/DrHalfBaked/PowerShell.MaterialDesign
9 | # LinkedIn - https://www.linkedin.com/in/avi-coren-6647b2105/
10 | #
11 | # Last file update: Dec 23, 2021 04:30
12 | #
13 | [Void][System.Reflection.Assembly]::LoadWithPartialName('presentationframework')
14 | [Void][System.Reflection.Assembly]::LoadFrom("$PSScriptRoot\Assembly\MaterialDesignThemes.Wpf.dll")
15 | [Void][System.Reflection.Assembly]::LoadFrom("$PSScriptRoot\Assembly\MaterialDesignColors.dll")
16 |
17 | [regex]$Script:RegEx_Numbers = '^[0-9]*$'
18 | [regex]$Script:RegEx_AlphaNumeric = '^[a-zA-Z0-9]*$'
19 | [regex]$Script:RegEx_Letters = '^[a-zA-Z]*$'
20 | [regex]$Script:RegEx_LettersSpace = '^[\sa-zA-Z]*$'
21 | [regex]$Script:RegEx_AlphaNumericSpaceUnderscore = '^[\s_a-zA-Z0-9]*$'
22 | [regex]$Script:RegEx_NoteChars = '^[\s_\"\.\-,a-zA-Z0-9]*$'
23 | [regex]$Script:RegEx_EmailChars = '^[\@\.\-a-zA-Z0-9]*$'
24 | [regex]$Script:RegEx_EmailPattern = '^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$'
25 | [regex]$Script:RegEx_NumbersDash = '^[\-0-9]*$'
26 |
27 | # New-Window - Sets a new WPF window from a xaml file and declares all named elements as variables. It will also optionally set a Snackbar Queue.
28 | # New-Snackbar - Generates a Snackbar message with an optional button.
29 | # Set-NavigationRailTab - Accepts a TabControl and tab name parameters and sets the tab name as selected tab.
30 | # Get-NavigationRailSelectedTabName - Returns the name of the current selected tab of a TabControl.
31 | # Get-SaveFilePath - Opens a save-file windows dialog and returns the name and path of the file to be saved.
32 | # Get-OpenFilePath - Opens a open-file windows dialog and returns the name and path of the file to be opened.
33 | # Open-File - Opens a file and gets its content based on the FileType parameter. default is Get-Content.
34 | # Set-CurrentCulture - Sets the PS Session's culture. All Time and Date UI controls will be effected by that. (DatePicker for example).
35 | # Set-OutlinedProperty - Alters the visual style of some properties of a Material Design outlined UI control.
36 | # Set-ValidationError - (1)Marks/Clears an element's validity, (2)Will return an element vaildity state, (3)Will set an error message for invalid element.
37 | # Confirm-RequiredField - Will call Set-ValidationError to Mark/Clear an element if its text is $null or not respectively.
38 | # Confirm-TextPatternField - Will call Set-ValidationError to Mark/Clear an element if its text does not match or matches a regular expression respectively.
39 | # Confirm-TextInput - Blocks character from entered into an input element, based on a regular expression match
40 |
41 | function New-Window {
42 | param (
43 | $XamlFile,
44 | [Switch]$NoSnackbar
45 | )
46 |
47 | try {
48 | [xml]$Xaml = (Get-content $XamlFile)
49 | $Reader = New-Object System.Xml.XmlNodeReader $Xaml
50 | $Window = [Windows.Markup.XamlReader]::Load($Reader)
51 |
52 | $Xaml.SelectNodes("//*[@Name]") | ForEach-Object { Set-Variable -Name ($_.Name) -Value $Window.FindName($_.Name) -Scope Script }
53 | # Objects that have to be declared before the window launches (will run in the same dispatcher thread as the window)
54 | if (!$NoSnackbar){
55 | $Script:MessageQueue = [MaterialDesignThemes.Wpf.SnackbarMessageQueue]::new()
56 | $Script:MessageQueue.DiscardDuplicates = $true
57 | }
58 |
59 | return $Window
60 | }
61 | catch {
62 | Write-Error "Error building Xaml data or loading window data.`n$_"
63 | exit
64 | }
65 | }
66 |
67 | function New-Snackbar {
68 | param (
69 | $Snackbar,
70 | $Text,
71 | $ButtonCaption
72 | )
73 | try{
74 | if ($ButtonCaption) {
75 | $MessageQueue.Enqueue($Text, $ButtonCaption, {$null}, $null, $false, $false, [TimeSpan]::FromHours( 9999 ))
76 | }
77 | else {
78 | $MessageQueue.Enqueue($Text, $null, $null, $null, $false, $false, $null)
79 | }
80 | $Snackbar.MessageQueue = $MessageQueue
81 | }
82 | catch{
83 | Write-Error "No MessageQueue was declared in the window. Make sure -NoSnackbar switch wasn't used in New-Window`n$_"
84 | }
85 | }
86 |
87 | function Set-NavigationRailTab {
88 | param (
89 | $NavigationRail,
90 | $TabName
91 | )
92 | $NavigationRail.SelectedIndex = [array]::IndexOf((($NavigationRail.Items | Select-Object -ExpandProperty name).toupper()), $TabName.ToUpper())
93 | }
94 |
95 | function Get-NavigationRailSelectedTabName {
96 | param (
97 | $NavigationRail
98 | )
99 | return $NavigationRail.Items | Where-Object {$_.IsSelected -eq "True"} | Select-Object -ExpandProperty name
100 | }
101 |
102 | function Get-SaveFilePath {
103 | Param (
104 | [string] $InitialDirectory,
105 | [string] $Filter
106 | )
107 | try {
108 | $SaveFileDialog = [Microsoft.Win32.SaveFileDialog]::New()
109 | $SaveFileDialog.initialDirectory = $InitialDirectory
110 | $SaveFileDialog.filter = $Filter
111 | $SaveFileDialog.CreatePrompt = $False;
112 | $SaveFileDialog.OverwritePrompt = $True;
113 | $SaveFileDialog.ShowDialog() | Out-Null
114 | return $SaveFileDialog.filename
115 | }
116 | catch {
117 | Write-Error "Error in Get-SaveFilePath common function`n$_"
118 | }
119 | }
120 |
121 | function Get-OpenFilePath {
122 | Param (
123 | [string] $InitialDirectory,
124 | [string] $Filter
125 | )
126 | try{
127 | $OpenFileDialog = [Microsoft.Win32.OpenFileDialog]::New()
128 | $OpenFileDialog.initialDirectory = $InitialDirectory
129 | $OpenFileDialog.filter = $Filter
130 | # Examples of other common filters: "Word Documents|*.doc|Excel Worksheets|*.xls|PowerPoint Presentations|*.ppt |Office Files|*.doc;*.xls;*.ppt |All Files|*.*"
131 | $OpenFileDialog.ShowDialog() | Out-Null
132 | return $OpenFileDialog.filename
133 | }
134 | catch {
135 | Write-Error "Error in Get-OpenFilePath common function`n$_"
136 | }
137 | }
138 |
139 | function Open-File {
140 | param(
141 | $Path,
142 | $FileType
143 | )
144 | try {
145 | if (!(Test-Path $Path)) {
146 | Write-error "File $Path not found"
147 | return
148 | }
149 | switch ($FileType) {
150 | "xml" {
151 | [xml]$OutputFile = (Get-content $Path)
152 | }
153 | "csv" {
154 | $OutputFile = (Import-Csv -Path $Path -Encoding UTF8)
155 | }
156 | default {
157 | $OutputFile = (Get-content $Path)
158 | }
159 | }
160 | return $OutputFile
161 | } catch {
162 | Write-error "Error in Open-File common function`n$_"
163 | }
164 | }
165 |
166 | function Set-CurrentCulture {
167 | param(
168 | $LCID = 2057
169 | )
170 | # 2057 = English (UK) , 1033 = English (US)
171 | $culture = [System.Globalization.CultureInfo]::GetCultureInfo($LCID)
172 | [System.Threading.Thread]::CurrentThread.CurrentUICulture = $culture
173 | [System.Threading.Thread]::CurrentThread.CurrentCulture = $culture
174 | }
175 |
176 |
177 | function Set-OutlinedProperty {
178 | param (
179 | [System.Management.Automation.PSObject[]]$InputObject,
180 | $Padding, # "2"
181 | $FloatingOffset, # "-15, 0"
182 | $FloatingScale, # "1.2"
183 | $Opacity, # "0.75"
184 | $FontSize
185 | )
186 | try {
187 | foreach($UIObject in $InputObject) {
188 | if($Padding){
189 | $UIObject.padding = [System.Windows.Thickness]::new($Padding)
190 | }
191 | if($FloatingOffset){
192 | [MaterialDesignThemes.Wpf.HintAssist]::SetFloatingOffset( $UIObject, $FloatingOffset)
193 | }
194 | if($FloatingScale){
195 | [MaterialDesignThemes.Wpf.HintAssist]::SetFloatingScale( $UIObject, $FloatingScale)
196 | }
197 | if($FontSize){
198 | $UIObject.FontSize = $FontSize
199 | }
200 | if($Opacity){
201 | $UIObject.Opacity = $Opacity
202 | }
203 | $UIObject.VerticalContentAlignment = "Center"
204 |
205 | }
206 | }
207 | catch {
208 | Write-Error "Error in Set-OutlinedProperty common function`n$_"
209 | }
210 | }
211 |
212 | function Set-ValidationError {
213 | param (
214 | $UIObject,
215 | $ErrorText,
216 | [switch]$CheckHasError,
217 | [switch]$ClearInvalid
218 | )
219 | #https://coderedirect.com/questions/546371/setting-validation-error-template-from-code-in-wpf
220 | # !!! you must put Text="{Binding txt}" in the textbox xaml code.
221 | $ClassProperty =
222 | switch($UIObject.GetType().name) {
223 | "TextBox" {[System.Windows.Controls.TextBox]::TextProperty}
224 | "ComboBox" {[System.Windows.Controls.ComboBox]::SelectedItemProperty}
225 | "TimePicker" {[MaterialDesignThemes.Wpf.TimePicker]::TextProperty}
226 | "DatePicker" {[System.Windows.Controls.DatePicker]::SelectedDateProperty}
227 | # For RatingBar - you must put this in the xaml part --> Value="{Binding Path=BlaBla, Mode=TwoWay}" . Also don't use the Validation.ErrorTemplate attribute. It will show red border, no text.
228 | "RatingBar" {[MaterialDesignThemes.Wpf.RatingBar]::ValueProperty}
229 | #"Calendar" {[System.Windows.Controls.Calendar]::SelectedDateProperty} Wasn't tested yet
230 | #"ListBox" {[System.Windows.Controls.ListBox]::SelectedItemProperty} Wasn't tested yet
231 | #"RadioButton" {[System.Windows.Controls.RadioButton]::IsCheckedProperty} Wasn't tested yet
232 | # "PasswordBox" {[system.Windows.Controls.PasswordBox]::Password} Wasn't tested yet
233 | #"RichTextBox" {[System.Windows.Controls.RichTextBox]::Document} Wasn't tested yet
234 |
235 | }
236 | [System.Windows.Data.BindingExpression]$bindingExpression = [System.Windows.Data.BindingOperations]::GetBindingExpression( $UIObject, $ClassProperty)
237 | [System.Windows.Data.BindingExpressionBase]$bindingExpressionBase = [System.Windows.Data.BindingOperations]::GetBindingExpressionBase($UIObject, $ClassProperty);
238 | [System.Windows.Controls.ValidationError]$validationError = [System.Windows.Controls.ValidationError]::new([System.Windows.Controls.ExceptionValidationRule]::New(),$bindingExpression)
239 |
240 | <# This option will put the error message on either Absolute,AbsolutPoint,Bottom,Center,Custom,Left,Right,Top,MousePoint,Mouse,Relative,RelativePoint. Default is bottom.
241 | [MaterialDesignThemes.Wpf.ValidationAssist]::SetUsePopup($UIObject,$true)
242 | [MaterialDesignThemes.Wpf.ValidationAssist]::SetPopupPlacement($UIObject,[System.Windows.Controls.Primitives.PlacementMode]::Top)
243 | #>
244 | if($CheckHasError){
245 | return [System.Windows.Controls.Validation]::GetHasError($UIObject)
246 | }
247 | else {
248 | if ($ClearInvalid){
249 | [System.Windows.Controls.Validation]::ClearInvalid($bindingExpressionBase)
250 | }
251 | else{
252 | $validationError.ErrorContent = $ErrorText
253 | [System.Windows.Controls.Validation]::MarkInvalid($bindingExpressionBase,$validationError)
254 | }
255 | }
256 | }
257 |
258 | function Confirm-RequiredField {
259 | param (
260 | $UI_Object = $this,
261 | $ErrorText = "This field is mandatory"
262 | )
263 | if (!$UI_Object.Text) {
264 | Set-ValidationError -UIObject $UI_Object -ErrorText $ErrorText
265 | }
266 | else {
267 | Set-ValidationError -UIObject $UI_Object -ClearInvalid
268 | }
269 | }
270 |
271 | function Confirm-TextPatternField {
272 | param (
273 | $UI_Object = $this,
274 | $ErrorText = "Invalid Value",
275 | [regex[]]$Regex
276 | )
277 | $IsValid = $false
278 | foreach ($Pattern in $Regex) {
279 | if ($UI_Object.Text -match $Pattern) {
280 | $IsValid = $true
281 | break
282 | }
283 | }
284 | if ($IsValid){
285 | Set-ValidationError -UIObject $UI_Object -ClearInvalid
286 | }
287 | else {
288 | Set-ValidationError -UIObject $UI_Object -ErrorText $ErrorText
289 | }
290 | }
291 |
292 | function Confirm-TextInput {
293 | param(
294 | $UI_Object = $this,
295 | $RegexPattern,
296 | [switch]$ToUpper
297 | )
298 | $SelectionStart = $UI_Object.SelectionStart
299 | $TextLength = ($UI_Object.text).length
300 | $TmpArray = $UI_Object.text.ToCharArray()
301 | $Output = $TmpArray | ForEach-Object { $_ | Where-Object { $_ -match $RegexPattern } }
302 | $UI_Object.text = if($ToUpper) {(-join $Output).ToUpper()} else {(-join $Output)}
303 | if ( ($UI_Object.text).length -lt $TextLength ) {
304 | $UI_Object.SelectionStart = $SelectionStart - 1
305 | } else { $UI_Object.SelectionStart = $SelectionStart }
306 | }
307 |
308 |
--------------------------------------------------------------------------------
/CommonTheme.ps1:
--------------------------------------------------------------------------------
1 | ###########
2 | # Learn how to build Material Design based PowerShell apps
3 | #
4 | # Common Functions and Assemblies related to Themes
5 | #
6 | # Avi Coren (c)
7 | # Blog - https://www.materialdesignps.com
8 | # Github - https://github.com/DrHalfBaked/PowerShell.MaterialDesign
9 | # LinkedIn - https://www.linkedin.com/in/avi-coren-6647b2105/
10 | #
11 | # Last file update: Dec 23, 2021 04:30
12 | #
13 |
14 | [System.Collections.ArrayList]$ThemePrimaryColors = [System.Enum]::GetNames([MaterialDesignColors.PrimaryColor])
15 | $ThemePrimaryColors.Sort()
16 | [System.Collections.ArrayList]$ThemeSecondaryColors = [System.Enum]::GetNames([MaterialDesignColors.SecondaryColor])
17 | $ThemeSecondaryColors.Sort()
18 |
19 |
20 |
21 | # Set-Theme - Sets the window theme colors and mode
22 | # Get-ThemeMode - Returns the given app window theme mode ("Dark" or "Light")
23 | # Get-SystemTheme - Will return "Dark" or "Light" based on the current apps theme mode set in windows OS
24 |
25 | function Set-Theme {
26 | param(
27 | $Window,
28 | $PrimaryColor,
29 | $SecondaryColor,
30 | [Parameter()]
31 | [ValidateSet('Dark', 'Light')]
32 | $ThemeMode
33 | )
34 | $Theme = [MaterialDesignThemes.Wpf.ResourceDictionaryExtensions]::GetTheme($Window.Resources)
35 | if($PrimaryColor) {
36 | $PrimaryColorObj = [MaterialDesignColors.SwatchHelper]::Lookup[$PrimaryColor]
37 | [void][MaterialDesignThemes.Wpf.ThemeExtensions]::SetPrimaryColor($Theme, $PrimaryColorObj)
38 | }
39 | if($SecondaryColor) {
40 | $SecondaryColorObj = [MaterialDesignColors.SwatchHelper]::Lookup[$SecondaryColor]
41 | [void][MaterialDesignThemes.Wpf.ThemeExtensions]::SetSecondaryColor($Theme, $SecondaryColorObj)
42 | }
43 | if($ThemeMode) {
44 | [void][MaterialDesignThemes.Wpf.ThemeExtensions]::SetBaseTheme($Theme, [MaterialDesignThemes.Wpf.Theme]::$ThemeMode)
45 | }
46 | [void][MaterialDesignThemes.Wpf.ResourceDictionaryExtensions]::SetTheme($Window.Resources, $Theme)
47 | }
48 |
49 | function Get-ThemeMode {
50 | param(
51 | $Window
52 | )
53 | $Theme = [MaterialDesignThemes.Wpf.ResourceDictionaryExtensions]::GetTheme($Window.Resources)
54 | return [MaterialDesignThemes.Wpf.ThemeExtensions]::GetBaseTheme($Theme)
55 | }
56 |
57 | function Get-SystemTheme {
58 | return [MaterialDesignThemes.Wpf.Theme]::GetSystemTheme()
59 | }
--------------------------------------------------------------------------------
/Content of Examples.txt:
--------------------------------------------------------------------------------
1 | Example1 - Input text to top textbox then button click displays text in the bottom textbox {change textbox to an outlined field}
2 | Example2 - Open and Save Dialog boxes. Floating Mini Buttons, OutlinedTextBox
3 | Example3 - SnackBars {move the xaml snackbar around to show that its at the bottom and when in stackpanel it pushes items. finally put it in a DockPanel below the stackpanel (with margin) and show the opacity problem}
4 | Example4 - DataTable / DataGrid {Task: Add a refresh button to get new data, text has no validation yet}
5 | Example5 -
6 | Example6 - Tab Control (Navigation Rails)
7 | Example7 - Tab Control (Navigation Rails) with popup box and left drawer
8 | Example8 - Tab awareness + introducing common files
9 | Example9 - Forms
10 | Example9b - Forms with input validation
11 | Example10 - Multiple DialogBoxes?
12 | Example11 - Context menu in TextBox
13 | Example12 -
14 | Example13 - Introducing Theme
15 | Example14 -
16 | Example15 - The Spinner and Runspace
17 | Example16 -
18 | Example17 - DataTable With "Gmail-like" controls
19 |
20 |
21 |
--------------------------------------------------------------------------------
/Example.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Light
6 | Purple
7 | Amber
8 |
9 |
10 | 900
11 | 1427
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/Example1.ps1:
--------------------------------------------------------------------------------
1 | ###########
2 | # Learn how to build Material Design based PowerShell apps
3 | # --------------------
4 | # Example1: Hello World
5 | # --------------------
6 | # Avi Coren (c)
7 | # Blog - https://www.materialdesignps.com
8 | # Github - https://github.com/DrHalfBaked/PowerShell.MaterialDesign
9 | # LinkedIn - https://www.linkedin.com/in/avi-coren-6647b2105/
10 | #
11 | [Void][System.Reflection.Assembly]::LoadWithPartialName('presentationframework')
12 | [Void][System.Reflection.Assembly]::LoadFrom("$PSScriptRoot\Assembly\MaterialDesignThemes.Wpf.dll")
13 | [Void][System.Reflection.Assembly]::LoadFrom("$PSScriptRoot\Assembly\MaterialDesignColors.dll")
14 |
15 | try {
16 | [xml]$Xaml = (Get-content "$PSScriptRoot\Example1.xaml")
17 | $Reader = New-Object System.Xml.XmlNodeReader $Xaml
18 | $Window = [Windows.Markup.XamlReader]::Load($Reader)
19 | }
20 | catch {
21 | Write-Error "Error building Xaml data.`n$_"
22 | exit
23 | }
24 |
25 | $Xaml.SelectNodes("//*[@Name]") | ForEach-Object { Set-Variable -Name ($_.Name) -Value $Window.FindName($_.Name) -Scope Script }
26 |
27 | $Btn1.Add_Click({$TxtBox2.Text = $TxtBox1.Text})
28 |
29 |
30 | $Window.ShowDialog() | out-null
--------------------------------------------------------------------------------
/Example1.xaml:
--------------------------------------------------------------------------------
1 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/Example11.ps1:
--------------------------------------------------------------------------------
1 | ###########
2 | # Learn how to build Material Design based PowerShell apps
3 | # --------------------
4 | # Example11: Context menu in TextBox
5 | # --------------------
6 | # Avi Coren (c)
7 | # Blog - https://www.materialdesignps.com
8 | # Github - https://github.com/DrHalfBaked/PowerShell.MaterialDesign
9 | # LinkedIn - https://www.linkedin.com/in/avi-coren-6647b2105/
10 | #
11 | Get-ChildItem -Path $PSScriptRoot -Filter Common*.PS1 | ForEach-Object {. ($_.FullName)}
12 |
13 | $Window = New-Window -XamlFile "$PSScriptRoot\Example11.xaml"
14 |
15 | $InitialDirectory = "$([Environment]::GetFolderPath("MyDocuments"))"
16 | $FileFilter = "Text files|*.txt|All Files|*.*"
17 |
18 | $Btn_OpenFile.add_Click({ On_OpenFile })
19 | $Btn_SaveFile.add_Click({ On_SaveFile })
20 | $TextBox_Editor_CopySelectedToClipboard_MenuItm.add_Click({ On_CopySelectedToClipboard })
21 | $TextBox_Editor_CopyAllToClipboard_MenuItm.add_Click({ On_CopyAllToClipboard })
22 | $TextBox_Editor_PasteFromClipboard_MenuItm.add_Click({ On_PasteFromClipboard })
23 | $TextBox_Editor_CutToClipboard_MenuItm.add_Click({ On_CutToClipboard })
24 | function On_OpenFile {
25 | $OpenedFile = Get-OpenFilePath -InitialDirectory $InitialDirectory -Filter $FileFilter
26 | if ($OpenedFile) {
27 | $TextBox_Editor.Text = Get-content $OpenedFile -Raw
28 | }
29 | }
30 |
31 | function On_SaveFile {
32 | $SavePath = Get-SaveFilePath -InitialDirectory $InitialDirectory -Filter $FileFilter
33 | if ($SavePath) {
34 | $TextBox_Editor.Text | Out-File -FilePath $SavePath -Encoding UTF8
35 | }
36 | }
37 |
38 | function On_CopySelectedToClipboard {
39 | $TextBox_Editor.Copy()
40 | }
41 |
42 | function On_CopyAllToClipboard {
43 | [System.Windows.Clipboard]::SetText($TextBox_Editor.Text)
44 | }
45 |
46 | function On_PasteFromClipboard {
47 | $TextBox_Editor.Paste()
48 | }
49 |
50 | function On_CutToClipboard {
51 | $TextBox_Editor.Cut()
52 | }
53 |
54 |
55 | $Window.ShowDialog() | out-null
--------------------------------------------------------------------------------
/Example11.xaml:
--------------------------------------------------------------------------------
1 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
36 |
39 |
40 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/Example13.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Light
6 | LightBlue
7 | Indigo
8 |
9 |
10 |
--------------------------------------------------------------------------------
/Example13.ps1:
--------------------------------------------------------------------------------
1 | ###########
2 | # Learn how to build Material Design based PowerShell apps
3 | # --------------------
4 | # Example13: Introducing Theme
5 | # --------------------
6 | # Avi Coren (c)
7 | # Blog - https://www.materialdesignps.com
8 | # Github - https://github.com/DrHalfBaked/PowerShell.MaterialDesign
9 | # LinkedIn - https://www.linkedin.com/in/avi-coren-6647b2105/
10 | #
11 | Get-ChildItem -Path $PSScriptRoot -Filter Common*.PS1 | ForEach-Object {. ($_.FullName)}
12 |
13 | $Window = New-Window -XamlFile "$PSScriptRoot\Example13.xaml"
14 | $ConfigFilePath = "$PSScriptRoot\Example13.config"
15 | $ConfigXML = Open-File -Path $ConfigFilePath -FileType xml
16 |
17 | Set-Theme -Window $Window -PrimaryColor $ConfigXML.Parameters.Settings.Theme.PrimaryColor -SecondaryColor $ConfigXML.Parameters.Settings.Theme.SecondaryColor -ThemeMode $ConfigXML.Parameters.Settings.Theme.Mode
18 |
19 | $LeftDrawer_PrimaryColor_LstBox.Itemssource = $ThemePrimaryColors
20 | $LeftDrawer_SecondaryColor_LstBox.Itemssource = $ThemeSecondaryColors
21 | $LeftDrawer_ThemeMode_TglBtn.IsChecked = if((Get-ThemeMode -Window $Window) -eq "Dark") {$true} else {$false}
22 |
23 | [scriptblock]$OnClosingLeftDrawer = {
24 | $DrawerHost.IsLeftDrawerOpen = $false
25 | $LeftDrawer_Open_TglBtn.IsChecked = $false
26 | $LeftDrawer_Open_TglBtn.Visibility="Visible"
27 | }
28 |
29 | $DrawerHost.add_DrawerClosing($OnClosingLeftDrawer)
30 |
31 | $LeftDrawer_Close_TglBtn.add_Click($OnClosingLeftDrawer)
32 |
33 | $LeftDrawer_Open_TglBtn.add_Click({
34 | $DrawerHost.IsLeftDrawerOpen = $true
35 | $LeftDrawer_Close_TglBtn.IsChecked = $true
36 | $LeftDrawer_Open_TglBtn.Visibility="Hidden"
37 | })
38 |
39 | $LeftDrawer_ThemeMode_TglBtn.Add_Click({
40 | $ThemeMode = if ($LeftDrawer_ThemeMode_TglBtn.IsChecked -eq $true) {"Dark"} else {"Light"}
41 | Set-Theme -Window $Window -ThemeMode $ThemeMode
42 | })
43 |
44 | $LeftDrawer_PrimaryColor_LstBox.Add_SelectionChanged( {
45 | if ($this.IsMouseCaptured ) { # this condition prvents the event to be triggered when listbox selection is changed programatically
46 | Set-Theme -Window $Window -PrimaryColor $LeftDrawer_PrimaryColor_LstBox.SelectedValue
47 | }
48 | })
49 |
50 | $LeftDrawer_SecondaryColor_LstBox.Add_SelectionChanged( {
51 | if ($this.IsMouseCaptured ) { # this condition prvents the event to be triggered when listbox selection is changed programatically
52 | Set-Theme -Window $Window -SecondaryColor $LeftDrawer_SecondaryColor_LstBox.SelectedValue
53 | }
54 | })
55 |
56 | $LeftDrawer_Theme_Undo_Btn.Add_Click( {
57 | Set-Theme -Window $Window -PrimaryColor $ConfigXML.Parameters.Settings.Theme.PrimaryColor -SecondaryColor $ConfigXML.Parameters.Settings.Theme.SecondaryColor -ThemeMode $ConfigXML.Parameters.Settings.Theme.Mode
58 | $LeftDrawer_ThemeMode_TglBtn.IsChecked = if((Get-ThemeMode -Window $Window) -eq "Dark") {$true} else {$false}
59 | $LeftDrawer_PrimaryColor_LstBox.SelectedIndex = $ThemePrimaryColors.indexof($ConfigXML.Parameters.Settings.Theme.PrimaryColor)
60 | $LeftDrawer_SecondaryColor_LstBox.SelectedIndex = $ThemeSecondaryColors.indexof($ConfigXML.Parameters.Settings.Theme.SecondaryColor)
61 | })
62 |
63 | $LeftDrawer_Theme_Apply_Btn.Add_Click( {
64 |
65 | $IsChanged = $false
66 | if (($LeftDrawer_PrimaryColor_LstBox.SelectedValue) -and $ConfigXML.Parameters.Settings.Theme.PrimaryColor -ne $LeftDrawer_PrimaryColor_LstBox.SelectedValue) {
67 | $IsChanged = $true
68 | $ConfigXML.Parameters.Settings.Theme.PrimaryColor = $LeftDrawer_PrimaryColor_LstBox.SelectedValue
69 | }
70 | if (($LeftDrawer_SecondaryColor_LstBox.SelectedValue) -and $ConfigXML.Parameters.Settings.Theme.SecondaryColor -ne $LeftDrawer_SecondaryColor_LstBox.SelectedValue) {
71 | $IsChanged = $true
72 | $ConfigXML.Parameters.Settings.Theme.SecondaryColor = $LeftDrawer_SecondaryColor_LstBox.SelectedValue
73 | }
74 | if (($ConfigXML.Parameters.Settings.Theme.Mode -eq "Light") -and ($LeftDrawer_ThemeMode_TglBtn.IsChecked)) {
75 | $IsChanged = $true
76 | $ConfigXML.Parameters.Settings.Theme.Mode = "Dark"
77 | }
78 | if (($ConfigXML.Parameters.Settings.Theme.Mode -eq "Dark") -and (!$LeftDrawer_ThemeMode_TglBtn.IsChecked)) {
79 | $IsChanged = $true
80 | $ConfigXML.Parameters.Settings.Theme.Mode = "Light"
81 | }
82 | if ($IsChanged) {
83 | try {
84 | $ConfigXML.Save($ConfigFilePath)
85 | New-Snackbar -Snackbar $MainSnackbar -Text "Theme was successfully saved"
86 | }
87 | catch {
88 | New-Snackbar -Snackbar $MainSnackbar -Text $_[0] -ButtonCaption "OK"
89 | return
90 | }
91 | }
92 | })
93 |
94 |
95 | $Window.ShowDialog() | out-null
--------------------------------------------------------------------------------
/Example13.xaml:
--------------------------------------------------------------------------------
1 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
50 |
51 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 | Light
75 |
76 | Dark
77 |
78 |
79 |
81 |
82 |
83 |
85 |
86 |
87 |
88 |
91 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
108 |
109 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
--------------------------------------------------------------------------------
/Example15.ps1:
--------------------------------------------------------------------------------
1 | ###########
2 | # Learn how to build Material Design based PowerShell apps
3 | # --------------------
4 | # Example15: Spinner and runspace
5 | # --------------------
6 | # Avi Coren (c)
7 | # Blog - https://www.materialdesignps.com
8 | # Github - https://github.com/DrHalfBaked/PowerShell.MaterialDesign
9 | # LinkedIn - https://www.linkedin.com/in/avi-coren-6647b2105/
10 | #
11 | Get-ChildItem -Path $PSScriptRoot -Filter Common*.PS1 | ForEach-Object {. ($_.FullName)}
12 |
13 | $Window = New-Window -XamlFile "$PSScriptRoot\Example15.xaml"
14 | $TextBox_Output.AppendText("Main Runspace ID: $(([System.Management.Automation.Runspaces.Runspace]::DefaultRunSpace).id)`n")
15 |
16 | $Btn_StartJob.Add_Click({
17 | $ApplicationLayer.IsEnabled = $false
18 | $SpinnerOverlayLayer.Visibility = "Visible"
19 |
20 | $Global:SyncHash = [hashtable]::Synchronized(@{
21 | Window = $window
22 | SpinnerOverlayLayer = $SpinnerOverlayLayer
23 | TextBox_Output = $TextBox_Output
24 | ApplicationLayer = $ApplicationLayer
25 | })
26 | $Runspace = [runspacefactory]::CreateRunspace()
27 | $Runspace.ThreadOptions = "ReuseThread"
28 | $Runspace.ApartmentState = "STA"
29 | $Runspace.Open()
30 | $Runspace.SessionStateProxy.SetVariable("SyncHash", $SyncHash)
31 | $Worker = [PowerShell]::Create().AddScript({
32 | $RunspaceID = ([System.Management.Automation.Runspaces.Runspace]::DefaultRunSpace).id
33 | $SyncHash.Window.Dispatcher.Invoke([action]{$SyncHash.TextBox_Output.AppendText("New Runspace ID: $RunspaceID`n")}, "Normal")
34 | $Results = [System.Text.StringBuilder]::new()
35 | foreach ($number in 1..10000000) {
36 | if (($number % 2560583 ) -eq 0) {
37 | [void]$Results.AppendLine($number)
38 | }
39 | }
40 | if($Results){
41 | $SyncHash.Window.Dispatcher.Invoke([action]{$SyncHash.TextBox_Output.AppendText($Results.ToString())}, "Normal")
42 | }
43 | $SyncHash.Window.Dispatcher.Invoke([action]{ $SyncHash.SpinnerOverlayLayer.Visibility = "Collapsed" }, "Normal")
44 | $SyncHash.Window.Dispatcher.Invoke([action]{ $SyncHash.ApplicationLayer.IsEnabled = $true }, "Normal")
45 |
46 | })
47 | $Worker.Runspace = $Runspace
48 |
49 | Register-ObjectEvent -InputObject $Worker -EventName InvocationStateChanged -Action {
50 | param([System.Management.Automation.PowerShell] $ps)
51 | $state = $EventArgs.InvocationStateInfo.State
52 | if ($state -in 'Completed', 'Failed') {
53 | $ps.EndInvoke($Worker)
54 | $ps.Runspace.Dispose()
55 | $ps.Dispose()
56 | [GC]::Collect()
57 | }
58 | } | Out-Null
59 |
60 | Register-ObjectEvent -InputObject $Runspace -EventName AvailabilityChanged -Action {
61 | if ($($EventArgs.RunspaceAvailability) -eq 'Available'){
62 | $Runspace.Dispose()
63 | [GC]::Collect()
64 | }
65 | } | Out-Null
66 |
67 | $Worker.BeginInvoke()
68 |
69 | })
70 |
71 | $Window.ShowDialog() | out-null
--------------------------------------------------------------------------------
/Example15.xaml:
--------------------------------------------------------------------------------
1 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/Example17.ps1:
--------------------------------------------------------------------------------
1 | ###########
2 | # Learn how to build Material Design based PowerShell apps
3 | # --------------------
4 | # Example17: DataTable With Gmail-like controls
5 | # --------------------
6 | # Avi Coren (c)
7 | # Blog - https://www.materialdesignps.com
8 | # Github - https://github.com/DrHalfBaked/PowerShell.MaterialDesign
9 | # LinkedIn - https://www.linkedin.com/in/avi-coren-6647b2105/
10 | #
11 | Get-ChildItem -Path $PSScriptRoot -Filter Common*.PS1 | ForEach-Object {. ($_.FullName)}
12 |
13 | $Window = New-Window -XamlFile "$PSScriptRoot\Example17.xaml"
14 |
15 | $Services_Datatable = [System.Data.DataTable]::New()
16 | [void]$Services_Datatable.Columns.Add('CheckboxSelect',[bool])
17 | [void]$Services_Datatable.Columns.AddRange(@('Name', 'Description', 'State', 'StartMode'))
18 | $Services_Datatable.primarykey = $Services_Datatable.columns['Name']
19 | $Services_DataGrid.ItemsSource = $Services_Datatable.DefaultView
20 | [System.Collections.ArrayList]$Script:SelectedRows = @()
21 |
22 | $Services = Get-CimInstance -ClassName Win32_service | Select-Object name, description, state, startmode
23 |
24 | foreach ($Service in $Services) {
25 | [void]$Services_Datatable.Rows.Add($false,$Service.Name, $Service.Description, $Service.State, $Service.StartMode)
26 | }
27 |
28 | $Services_DataGrid.add_SelectionChanged({ #Because we use checkboxes for row selection we have to disable the row click selection
29 | $_.Handled = $true
30 | })
31 |
32 | $Services_HeaderChkBox.add_Indeterminate({
33 | if ($_.OriginalSource.IsMouseOver) {
34 | $Services_HeaderChkBox.IsChecked = $false
35 | }
36 | })
37 |
38 | $Services_HeaderChkBox.add_Checked({
39 | if ($_.OriginalSource.IsMouseOver) {
40 | $Services_Datatable | ForEach-Object {$_.CheckboxSelect = $true}
41 | $Script:SelectedRows.Clear()
42 | $Script:SelectedRows += $Services_Datatable.Rows # Equivalent of $Services_DataGrid.SelectAll()
43 | write-host -ForegroundColor "Green" "Select all was ticked. $($SelectedRows.Count) records are selected"
44 | }
45 | })
46 |
47 | $Services_HeaderChkBox.add_UnChecked({
48 | if ($_.OriginalSource.IsMouseOver) {
49 | $Services_Datatable | ForEach-Object {$_.CheckboxSelect = $false}
50 | $SelectedRows.Clear() # Equivalent of $Services_DataGrid.SelectedItems.Clear()
51 | write-host -ForegroundColor "Red" "Unselect all was ticked. $($SelectedRows.Count) records are selected"
52 | }
53 | })
54 |
55 |
56 | $Services_DataGrid.Add_GotMouseCapture({
57 | $OriginalSourceName = $_.OriginalSource.Name
58 | if ($OriginalSourceName -ne "Services_HeaderChkBox") { # Ignore header checkbox click
59 | $DisplayIndex = $this.CurrentColumn.DisplayIndex # Returns the Column index (0 based) where the mouse was clicked on.
60 | $CurrentItemName = $this.CurrentItem.Name
61 | $OriginalSource = $_.OriginalSource
62 | switch (($_.OriginalSource).GetType().name) {
63 | "CheckBox" {
64 | $Row = $Services_Datatable.select("Name = '$($CurrentItemName)'") #The search column(s) must be the primary key (return only one result)
65 | $RowIndex = $Services_Datatable.Rows.IndexOf($Row[0])
66 | $Services_Datatable.Rows[$RowIndex].CheckboxSelect = !($Services_Datatable.Rows[$RowIndex].CheckboxSelect)
67 | $OriginalSource.IsChecked = !($OriginalSource.IsChecked) # It has to reflip to get to the right state.
68 | if (!$OriginalSource.IsChecked) {
69 | $SelectedRows.Add($Services_Datatable.Rows[$RowIndex])
70 | write-host -ForegroundColor "Blue" "$CurrentItemName was selected. $($SelectedRows.Count) records are selected"
71 | }
72 | else {
73 | $SelectedRows.RemoveAt( $SelectedRows.IndexOf( ($SelectedRows | Where-Object {$_.name -eq $CurrentItemName})))
74 | write-host -ForegroundColor "Blue" "$CurrentItemName was unselected. $($SelectedRows.Count) records are selected"
75 | }
76 | if ($Script:SelectedRows.Count -eq ($Script:Services_Datatable.Rows).Count ) {
77 | $Services_HeaderChkBox.IsChecked = $true
78 | }
79 | elseif ($Script:SelectedRows.Count -eq 0) {
80 | $Services_HeaderChkBox.IsChecked = $false
81 | }
82 | else {
83 | $Services_HeaderChkBox.IsChecked = $null
84 | }
85 | break
86 | }
87 | "Button" {
88 | switch ($OriginalSourceName) {
89 | "Services_DeleteButton" {write-host -ForegroundColor "Cyan" "Delete action was clicked on Item $CurrentItemName"}
90 | "Services_ViewButton" {write-host -ForegroundColor "DarkYellow" "View action was clicked on Item $CurrentItemName"}
91 | }
92 | break
93 | }
94 | }
95 | }
96 | })
97 |
98 | $async = $Window.Dispatcher.InvokeAsync( {
99 | $Window.ShowDialog()
100 | })
101 |
102 | $async.Wait() | Out-Null
--------------------------------------------------------------------------------
/Example17.xaml:
--------------------------------------------------------------------------------
1 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
33 |
36 |
37 |
46 |
47 |
48 |
56 |
57 |
58 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
73 |
74 |
75 |
76 |
77 |
78 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
--------------------------------------------------------------------------------
/Example2.ps1:
--------------------------------------------------------------------------------
1 | ###########
2 | # Learn how to build Material Design based PowerShell apps
3 | # --------------------
4 | # Example2: Open and Save Dialog boxes
5 | # --------------------
6 | # Avi Coren (c)
7 | # Blog - https://www.materialdesignps.com
8 | # Github - https://github.com/DrHalfBaked/PowerShell.MaterialDesign
9 | # LinkedIn - https://www.linkedin.com/in/avi-coren-6647b2105/
10 | #
11 | [Void][System.Reflection.Assembly]::LoadWithPartialName('presentationframework')
12 | [Void][System.Reflection.Assembly]::LoadFrom("$PSScriptRoot\Assembly\MaterialDesignThemes.Wpf.dll")
13 | [Void][System.Reflection.Assembly]::LoadFrom("$PSScriptRoot\Assembly\MaterialDesignColors.dll")
14 |
15 | try {
16 | [xml]$Xaml = (Get-content "$PSScriptRoot\Example2.xaml")
17 | $Reader = New-Object System.Xml.XmlNodeReader $Xaml
18 | $Window = [Windows.Markup.XamlReader]::Load($Reader)
19 | }
20 | catch {
21 | Write-Error "Error building Xaml data.`n$_"
22 | exit
23 | }
24 |
25 | $Xaml.SelectNodes("//*[@Name]") | ForEach-Object { Set-Variable -Name ($_.Name) -Value $Window.FindName($_.Name) -Scope Script }
26 |
27 | $InitialDirectory = "$([Environment]::GetFolderPath("MyDocuments"))"
28 | $FileFilter = "Text files|*.txt|All Files|*.*"
29 |
30 | function Save-File {
31 | Param (
32 | [string] $InitialDirectory,
33 | [string] $Filter
34 | )
35 | try {
36 | $SaveFileDialog = New-Object Microsoft.Win32.SaveFileDialog
37 | $SaveFileDialog.initialDirectory = $initialDirectory
38 | $SaveFileDialog.filter = $Filter
39 | $SaveFileDialog.CreatePrompt = $False;
40 | $SaveFileDialog.OverwritePrompt = $True;
41 | $SaveFileDialog.ShowDialog() | Out-Null
42 | return $SaveFileDialog.filename
43 | }
44 | catch {
45 | Throw "Save-File Error $_"
46 | }
47 | }
48 |
49 | function Open-File {
50 | Param (
51 | [string] $InitialDirectory,
52 | [string] $Filter
53 | )
54 | try{
55 | $OpenFileDialog = New-Object Microsoft.Win32.OpenFileDialog
56 | $OpenFileDialog.initialDirectory = $initialDirectory
57 | $OpenFileDialog.filter = $Filter
58 | # Examples of other common filters: "Word Documents|*.doc|Excel Worksheets|*.xls|PowerPoint Presentations|*.ppt |Office Files|*.doc;*.xls;*.ppt |All Files|*.*"
59 | $OpenFileDialog.ShowDialog() | Out-Null
60 | return $OpenFileDialog.filename
61 | }
62 | catch {
63 | Throw "Open-File Error $_"
64 | }
65 | }
66 |
67 | $Btn_OpenFile.Add_Click({ On_OpenFile })
68 | $Btn_SaveFile.Add_Click({ On_SaveFile })
69 |
70 | Function On_OpenFile {
71 | $OpenedFile = Open-File -InitialDirectory $InitialDirectory -Filter $FileFilter
72 | if ($OpenedFile) {
73 | $TextBox_Editor.Text = Get-content $OpenedFile -Raw
74 | }
75 | }
76 |
77 | Function On_SaveFile {
78 | $SavePath = Save-File -InitialDirectory $InitialDirectory -Filter $FileFilter
79 | if ($SavePath) {
80 | $TextBox_Editor.Text | Out-File -FilePath $SavePath -Encoding UTF8
81 | }
82 | }
83 |
84 |
85 | $Window.ShowDialog() | out-null
--------------------------------------------------------------------------------
/Example2.xaml:
--------------------------------------------------------------------------------
1 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
36 |
39 |
40 |
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/Example3.ps1:
--------------------------------------------------------------------------------
1 | ###########
2 | # Learn how to build Material Design based PowerShell apps
3 | # --------------------
4 | # Example3: SnackBars
5 | # --------------------
6 | # Avi Coren (c)
7 | # Blog - https://www.materialdesignps.com
8 | # Github - https://github.com/DrHalfBaked/PowerShell.MaterialDesign
9 | # LinkedIn - https://www.linkedin.com/in/avi-coren-6647b2105/
10 | #
11 | [Void][System.Reflection.Assembly]::LoadWithPartialName('presentationframework')
12 | [Void][System.Reflection.Assembly]::LoadFrom("$PSScriptRoot\Assembly\MaterialDesignThemes.Wpf.dll")
13 | [Void][System.Reflection.Assembly]::LoadFrom("$PSScriptRoot\Assembly\MaterialDesignColors.dll")
14 |
15 | try {
16 | [xml]$Xaml = (Get-content "$PSScriptRoot\Example3.xaml")
17 | $Reader = New-Object System.Xml.XmlNodeReader $Xaml
18 | $Window = [Windows.Markup.XamlReader]::Load($Reader)
19 | }
20 | catch {
21 | Write-Error "Error building Xaml data.`n$_"
22 | exit
23 | }
24 |
25 | $Xaml.SelectNodes("//*[@Name]") | ForEach-Object { Set-Variable -Name ($_.Name) -Value $Window.FindName($_.Name) -Scope Script }
26 |
27 |
28 | $MessageQueue = [MaterialDesignThemes.Wpf.SnackbarMessageQueue]::new()
29 | $MessageQueue.DiscardDuplicates = $true
30 |
31 | function New-Snackbar {
32 | param (
33 | $Snackbar,
34 | $Text,
35 | $ButtonCaption
36 | )
37 | if ($ButtonCaption) {
38 | $MessageQueue.Enqueue($Text, $ButtonCaption, {$null}, $null, $false, $false, [TimeSpan]::FromHours( 9999 ))
39 | # 7 Arguments of Enqueue: content, actionContent, actionHandler, actionArgument, promote, neverConsiderToBeDuplicate, durationOverride
40 | }
41 | else {
42 | $MessageQueue.Enqueue($Text, $null, $null, $null, $false, $false, $null)
43 | }
44 | $Snackbar.MessageQueue = $MessageQueue
45 | }
46 |
47 | $Btn_ShowSnkBarNoHide.Add_Click({New-Snackbar -Snackbar $Snackbar1 -Text $TxtBox_SnkBarContent.Text -ButtonCaption "OK"})
48 | $Btn_ShowSnkBarAutoHide.Add_Click({New-Snackbar -Snackbar $Snackbar1 -Text $TxtBox_SnkBarContent.Text})
49 |
50 | $Window.ShowDialog() | out-null
--------------------------------------------------------------------------------
/Example3.xaml:
--------------------------------------------------------------------------------
1 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/Example4.ps1:
--------------------------------------------------------------------------------
1 | ###########
2 | # Learn how to build Material Design based PowerShell apps
3 | # --------------------
4 | # Example4: DataTables
5 | # --------------------
6 | # Avi Coren (c)
7 | # Blog - https://www.materialdesignps.com
8 | # Github - https://github.com/DrHalfBaked/PowerShell.MaterialDesign
9 | # LinkedIn - https://www.linkedin.com/in/avi-coren-6647b2105/
10 | #
11 | [Void][System.Reflection.Assembly]::LoadWithPartialName('presentationframework')
12 | [Void][System.Reflection.Assembly]::LoadFrom("$PSScriptRoot\Assembly\MaterialDesignThemes.Wpf.dll")
13 | [Void][System.Reflection.Assembly]::LoadFrom("$PSScriptRoot\Assembly\MaterialDesignColors.dll")
14 |
15 | try {
16 | [xml]$Xaml = (Get-content "$PSScriptRoot\Example4.xaml")
17 | $Reader = New-Object System.Xml.XmlNodeReader $Xaml
18 | $Window = [Windows.Markup.XamlReader]::Load($Reader)
19 | }
20 | catch {
21 | Write-Error "Error building Xaml data.`n$_"
22 | exit
23 | }
24 |
25 | $Xaml.SelectNodes("//*[@Name]") | ForEach-Object { Set-Variable -Name ($_.Name) -Value $Window.FindName($_.Name) -Scope Script }
26 |
27 |
28 | $Services_Datatable = [System.Data.DataTable]::New()
29 | [void]$Services_Datatable.Columns.AddRange(@('Name', 'Description', 'State', 'StartMode'))
30 |
31 | Function FilterServices {
32 | $FilterString = [System.Text.StringBuilder]::New()
33 | if ( $Services_TxtBox_FilterByName.Text) {
34 | $FilterString.Append(" Name LIKE '%$($Services_TxtBox_FilterByName.Text)%' AND ")
35 | }
36 | if ($Services_ChkBox_FilterRunning.IsChecked) {
37 | $FilterString.Append("State LIKE 'Running'")
38 | }
39 | else {
40 | $FilterString.Append("State LIKE '%%'")
41 | }
42 | $Services_Datatable.DefaultView.RowFilter = $FilterString
43 | $Services_DataGrid.ItemsSource = $Services_Datatable.DefaultView
44 | }
45 |
46 | $Services = Get-CimInstance -ClassName Win32_service | Select-Object name, description, state, startmode
47 |
48 | foreach ($Service in $Services) {
49 | [void]$Services_Datatable.Rows.Add($Service.Name, $Service.Description, $Service.State, $Service.StartMode)
50 | }
51 |
52 | $Services_DataGrid.ItemsSource = $Services_Datatable.DefaultView
53 |
54 | $Services_TxtBox_FilterByName.Add_TextChanged({ FilterServices })
55 | $Services_ChkBox_FilterRunning.Add_Checked({ FilterServices })
56 | $Services_ChkBox_FilterRunning.Add_Unchecked({ FilterServices })
57 |
58 | $Window.ShowDialog() | out-null
--------------------------------------------------------------------------------
/Example4.xaml:
--------------------------------------------------------------------------------
1 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
38 |
39 |
40 |
42 |
44 |
45 |
46 |
48 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
--------------------------------------------------------------------------------
/Example6.ps1:
--------------------------------------------------------------------------------
1 | ###########
2 | # Learn how to build Material Design based PowerShell apps
3 | # --------------------
4 | # Example6: Tab Control (Navigation Rails)
5 | # --------------------
6 | # Avi Coren (c)
7 | # Blog - https://www.materialdesignps.com
8 | # Github - https://github.com/DrHalfBaked/PowerShell.MaterialDesign
9 | # LinkedIn - https://www.linkedin.com/in/avi-coren-6647b2105/
10 | #
11 | [Void][System.Reflection.Assembly]::LoadWithPartialName('presentationframework')
12 | [Void][System.Reflection.Assembly]::LoadFrom("$PSScriptRoot\Assembly\MaterialDesignThemes.Wpf.dll")
13 | [Void][System.Reflection.Assembly]::LoadFrom("$PSScriptRoot\Assembly\MaterialDesignColors.dll")
14 |
15 | try {
16 | [xml]$Xaml = (Get-content "$PSScriptRoot\Example6.xaml")
17 | $Reader = New-Object System.Xml.XmlNodeReader $Xaml
18 | $Window = [Windows.Markup.XamlReader]::Load($Reader)
19 | }
20 | catch {
21 | Write-Error "Error building Xaml data.`n$_"
22 | exit
23 | }
24 |
25 | $Xaml.SelectNodes("//*[@Name]") | ForEach-Object { Set-Variable -Name ($_.Name) -Value $Window.FindName($_.Name) -Scope Script }
26 |
27 | $Window.ShowDialog() | out-null
--------------------------------------------------------------------------------
/Example6.xaml:
--------------------------------------------------------------------------------
1 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
--------------------------------------------------------------------------------
/Example7.ps1:
--------------------------------------------------------------------------------
1 | ###########
2 | # Learn how to build Material Design based PowerShell apps
3 | # --------------------
4 | # Example7: Navigation Rails with a left Drawer and a right PopupBox
5 | # --------------------
6 | # Avi Coren (c)
7 | # Blog - https://www.materialdesignps.com
8 | # Github - https://github.com/DrHalfBaked/PowerShell.MaterialDesign
9 | # LinkedIn - https://www.linkedin.com/in/avi-coren-6647b2105/
10 | #
11 | [Void][System.Reflection.Assembly]::LoadWithPartialName('presentationframework')
12 | [Void][System.Reflection.Assembly]::LoadFrom("$PSScriptRoot\Assembly\MaterialDesignThemes.Wpf.dll")
13 | [Void][System.Reflection.Assembly]::LoadFrom("$PSScriptRoot\Assembly\MaterialDesignColors.dll")
14 |
15 | try {
16 | [xml]$Xaml = (Get-content "$PSScriptRoot\Example7.xaml")
17 | $Reader = New-Object System.Xml.XmlNodeReader $Xaml
18 | $Window = [Windows.Markup.XamlReader]::Load($Reader)
19 | }
20 | catch {
21 | Write-Error "Error building Xaml data.`n$_"
22 | exit
23 | }
24 |
25 | $Xaml.SelectNodes("//*[@Name]") | ForEach-Object { Set-Variable -Name ($_.Name) -Value $Window.FindName($_.Name) -Scope Script }
26 |
27 | [scriptblock]$OnClosingDrawer = {
28 | $DrawerHost.IsLeftDrawerOpen = $false
29 | $TglBtn_OpenLeftDrawer.IsChecked = $false
30 | $TglBtn_OpenLeftDrawer.Visibility="Visible"
31 | }
32 |
33 | $DrawerHost.add_DrawerClosing($OnClosingDrawer)
34 | $TglBtn_CloseLeftDrawer.add_Click($OnClosingDrawer)
35 |
36 | $TglBtn_OpenLeftDrawer.add_Click({
37 | $DrawerHost.IsLeftDrawerOpen = $true
38 | $TglBtn_CloseLeftDrawer.IsChecked = $true
39 | $TglBtn_OpenLeftDrawer.Visibility="Hidden"
40 | })
41 |
42 | $Window.ShowDialog() | out-null
--------------------------------------------------------------------------------
/Example7.xaml:
--------------------------------------------------------------------------------
1 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
--------------------------------------------------------------------------------
/Example8.ps1:
--------------------------------------------------------------------------------
1 | ###########
2 | # Learn how to build Material Design based PowerShell apps
3 | # --------------------
4 | # Example8: Navigation Rails - Tab awareness + introducing common files
5 | # --------------------
6 | # Avi Coren (c)
7 | # Blog - https://www.materialdesignps.com
8 | # Github - https://github.com/DrHalfBaked/PowerShell.MaterialDesign
9 | # LinkedIn - https://www.linkedin.com/in/avi-coren-6647b2105/
10 | #
11 | Get-ChildItem -Path $PSScriptRoot -Filter Common*.PS1 | ForEach-Object {. ($_.FullName)}
12 |
13 | $Window = New-Window -XamlFile "$PSScriptRoot\Example8.xaml"
14 |
15 | [scriptblock]$OnClosingDrawer = {
16 | $DrawerHost.IsLeftDrawerOpen = $false
17 | $TglBtn_OpenLeftDrawer.IsChecked = $false
18 | $TglBtn_OpenLeftDrawer.Visibility="Visible"
19 | }
20 |
21 | $DrawerHost.add_DrawerClosing($OnClosingDrawer)
22 |
23 | $TglBtn_CloseLeftDrawer.add_Click($OnClosingDrawer)
24 |
25 | $TglBtn_OpenLeftDrawer.add_Click({
26 | $DrawerHost.IsLeftDrawerOpen = $true
27 | $TglBtn_CloseLeftDrawer.IsChecked = $true
28 | $TglBtn_OpenLeftDrawer.Visibility="Hidden"
29 | })
30 |
31 | $LeftDrawerListBox1.add_SelectionChanged({
32 |
33 | switch ($LeftDrawerListBox1.SelectedItem.Content) {
34 | "Settings" {
35 | Set-NavigationRailTab -NavigationRail $NavRail -TabName "Settings"
36 | }
37 |
38 | "Open File" {
39 | $OpeneFilePath = Get-OpenFilePath -InitialDirectory $InitialDirectory -Filter $FileFilter
40 | if ($OpeneFilePath) {
41 | New-Snackbar -Snackbar $Snackbar1 -Text "You selected $OpeneFilePath"
42 | }
43 | }
44 |
45 | "Exit" {
46 | $Window.Close()
47 | }
48 | }
49 | $DrawerHost.IsLeftDrawerOpen = $false
50 | $LeftDrawerListBox1.SelectedIndex = -1
51 | })
52 |
53 | $NavRail.add_SelectionChanged({
54 | New-Snackbar -Snackbar $Snackbar1 -Text "You selected the $(Get-NavigationRailSelectedTabName -NavigationRail $NavRail) page"
55 | })
56 |
57 | $LeftDrawerListBox1.add_SelectionChanged({
58 |
59 | })
60 |
61 | $Window.ShowDialog() | out-null
--------------------------------------------------------------------------------
/Example8.xaml:
--------------------------------------------------------------------------------
1 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
59 |
60 |
61 |
62 |
63 |
64 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
84 |
85 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
--------------------------------------------------------------------------------
/Example9.ps1:
--------------------------------------------------------------------------------
1 | ###########
2 | # Learn how to build Material Design based PowerShell apps
3 | # --------------------
4 | # Example9: Forms without validations
5 | # --------------------
6 | # Avi Coren (c)
7 | # Blog - https://www.materialdesignps.com
8 | # Github - https://github.com/DrHalfBaked/PowerShell.MaterialDesign
9 | # LinkedIn - https://www.linkedin.com/in/avi-coren-6647b2105/
10 | #
11 |
12 | Get-ChildItem -Path $PSScriptRoot -Filter Common*.PS1 | ForEach-Object {. ($_.FullName)}
13 |
14 | $Window = New-Window -XamlFile "$PSScriptRoot\Example9.xaml"
15 |
16 | Get-Variable -Include "Car_Reg_Form_Textbox*","Car_Reg_Form_Combobox*","Car_Reg_Form_*Picker*" -ValueOnly |
17 | ForEach-Object { Set-OutlinedProperty -InputObject $_ -Padding "8" -FloatingOffset "1,-18" -FloatingScale "0.8" -Opacity "0.75" -FontSize 16 }
18 |
19 | $CarList = Import-Csv -Path "$PSScriptRoot\Cars.csv"
20 | $Car_Reg_Form_Combobox_Make.ItemsSource = ($CarList.Make | Select-Object -Unique | Sort-Object )
21 | $Car_Reg_Form_Combobox_Color.ItemsSource = ([System.Windows.Media.Colors].Getproperties() | Select-Object -ExpandProperty name | Sort-Object )
22 | $Car_Reg_Form_Combobox_Year.ItemsSource = (1990..2021)
23 |
24 | $Car_Reg_Form_Combobox_Make.add_SelectionChanged({
25 | $Car_Reg_Form_Combobox_Model.ItemsSource = $null
26 | $Car_Reg_Form_Combobox_Model.ItemsSource = ($CarList | Where-Object {$_.Make -eq $Car_Reg_Form_Combobox_Make.SelectedItem } | Select-Object -ExpandProperty Model | Select-Object -Unique | Sort-Object )
27 | })
28 |
29 | $Cars_Datatable = [System.Data.DataTable]::New()
30 | [void]$Cars_Datatable.Columns.AddRange(@('Plate', 'Make', 'Model', 'Year', 'Owner', 'Color', 'Note', 'Rating', 'DateReg', 'TimeReg'))
31 | $Cars_Datatable.primarykey = $Cars_Datatable.columns['Plate']
32 | $Cars_DataGrid.ItemsSource = $Cars_Datatable.DefaultView
33 |
34 | [scriptblock]$OnClosingDrawer = {
35 | $DrawerHost.IsLeftDrawerOpen = $false
36 | $TglBtn_OpenLeftDrawer.IsChecked = $false
37 | $TglBtn_OpenLeftDrawer.Visibility="Visible"
38 | }
39 |
40 | $DrawerHost.add_DrawerClosing($OnClosingDrawer)
41 | $TglBtn_CloseLeftDrawer.add_Click($OnClosingDrawer)
42 |
43 | $TglBtn_OpenLeftDrawer.add_Click({
44 | $DrawerHost.IsLeftDrawerOpen = $true
45 | $TglBtn_CloseLeftDrawer.IsChecked = $true
46 | $TglBtn_OpenLeftDrawer.Visibility="Hidden"
47 | })
48 |
49 | $Cars_Popup_Add_Car.Add_Click({ Set-NavigationRailTab -NavigationRail $NavRail -TabName "CarRegistration" })
50 |
51 | [scriptblock]$OnResetCarForm = {
52 | Get-Variable -Include "Car_Reg_Form_Combobox*" -ValueOnly | ForEach-Object {$_.SelectedItem = $null}
53 | Get-Variable -Include "Car_Reg_Form_Textbox*","Car_Reg_Form_*Picker*" -ValueOnly | ForEach-Object { $_.Text = $null }
54 | $Car_Reg_Form_RatingBar_Rate.Value = 0
55 | }
56 |
57 | $NavRail.add_SelectionChanged({
58 | if ($_.Source -like "System.Windows.Controls.TabControl*") {
59 | switch (Get-NavigationRailSelectedTabName -NavigationRail $NavRail) {
60 | "Users" { }
61 | "Cars" { }
62 | "CarRegistration" { }
63 | "Photos" { }
64 | "Movies" { }
65 | }
66 | }
67 | })
68 |
69 | $Car_Reg_Form_Btn_Reset.add_Click($OnResetCarForm)
70 | $Car_Reg_Form_Btn_Cancel.add_Click({
71 | Invoke-Command -Command $OnResetCarForm
72 | Set-NavigationRailTab -NavigationRail $NavRail -TabName "Cars"
73 | })
74 | $Car_Reg_Form_Btn_Apply.add_Click({
75 | $RowContent = @(
76 | $Car_Reg_Form_Textbox_Plate.Text
77 | $Car_Reg_Form_Combobox_Make.SelectedItem
78 | $Car_Reg_Form_Combobox_Model.SelectedItem
79 | $Car_Reg_Form_Combobox_Year.SelectedItem
80 | $Car_Reg_Form_Textbox_Owner.Text
81 | $Car_Reg_Form_Combobox_Color.SelectedItem
82 | $Car_Reg_Form_Textbox_Note.Text
83 | $Car_Reg_Form_RatingBar_Rate.Value
84 | $Car_Reg_Form_DatePicker_Registered.Text
85 | $Car_Reg_Form_TimePicker_Registered.Text
86 | )
87 | [void]$Cars_Datatable.Rows.Add($RowContent)
88 | Invoke-Command -Command $OnResetCarForm
89 | Set-NavigationRailTab -NavigationRail $NavRail -TabName "Cars"
90 | })
91 |
92 | $Window.ShowDialog() | out-null
--------------------------------------------------------------------------------
/Example9.xaml:
--------------------------------------------------------------------------------
1 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
60 |
61 |
62 |
63 |
64 |
65 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
207 |
210 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
--------------------------------------------------------------------------------
/Example9b.ps1:
--------------------------------------------------------------------------------
1 | ###########
2 | # Learn how to build Material Design based PowerShell apps
3 | # --------------------
4 | # Example9b: Forms with validations
5 | # --------------------
6 | # Avi Coren (c)
7 | # Blog - https://www.materialdesignps.com
8 | # Github - https://github.com/DrHalfBaked/PowerShell.MaterialDesign
9 | # LinkedIn - https://www.linkedin.com/in/avi-coren-6647b2105/
10 | #
11 | Get-ChildItem -Path $PSScriptRoot -Filter Common*.PS1 | ForEach-Object {. ($_.FullName)}
12 |
13 | $Window = New-Window -XamlFile "$PSScriptRoot\Example9b.xaml"
14 | Set-CurrentCulture
15 |
16 | Get-Variable -Include "Car_Reg_Form_Textbox*","Car_Reg_Form_Combobox*","Car_Reg_Form_*Picker*" -ValueOnly |
17 | ForEach-Object { Set-OutlinedProperty -InputObject $_ -Padding "8" -FloatingOffset "1,-18" -FloatingScale "0.8" -Opacity "0.75" -FontSize 16 }
18 | $CarList = Import-Csv -Path "$PSScriptRoot\Cars.csv"
19 | $Car_Reg_Form_Combobox_Make.ItemsSource = ($CarList.Make | Select-Object -Unique | Sort-Object )
20 | $Car_Reg_Form_Combobox_Color.ItemsSource = ([System.Windows.Media.Colors].Getproperties() | Select-Object -ExpandProperty name | Sort-Object )
21 | $Car_Reg_Form_Combobox_Year.ItemsSource = (1990..2021)
22 | $Car_Reg_Form_Textbox_Note.SpellCheck.IsEnabled = $true
23 | $Car_Reg_Form_Textbox_Owner.SpellCheck.IsEnabled = $true
24 |
25 | $Car_Reg_Form_Combobox_Make.add_SelectionChanged({
26 | $Car_Reg_Form_Combobox_Model.ItemsSource = $null
27 | $Car_Reg_Form_Combobox_Model.ItemsSource = ($CarList | Where-Object {$_.Make -eq $Car_Reg_Form_Combobox_Make.SelectedItem } | Select-Object -ExpandProperty Model | Select-Object -Unique | Sort-Object )
28 | })
29 |
30 | [scriptblock]$OnResetCarForm = {
31 | Get-Variable -Include "Car_Reg_Form_Combobox*" -ValueOnly | ForEach-Object {$_.SelectedItem = $null}
32 | Get-Variable -Include "Car_Reg_Form_Textbox*","Car_Reg_Form_*Picker*" -ValueOnly | ForEach-Object { $_.Text = $null }
33 | $Car_Reg_Form_RatingBar_Rate.Value = 0
34 | Get-Variable -Include "Car_Reg_Form_Textbox*","Car_Reg_Form_Combobox*","Car_Reg_Form_*Picker*" -ValueOnly | ForEach-Object {Set-ValidationError -UIObject $_ -ClearInvalid}
35 | }
36 |
37 | $Car_Reg_Form_Btn_Reset.add_Click($OnResetCarForm)
38 | $Car_Reg_Form_Btn_Cancel.add_Click({
39 | Invoke-Command -Command $OnResetCarForm
40 | Set-NavigationRailTab -NavigationRail $NavRail -TabName "Cars"
41 | })
42 | $Car_Reg_Form_Btn_Apply.add_Click({
43 | $FormHasErrors = $false
44 | Get-Variable -Include "Car_Reg_Form_Combobox*","Car_Reg_Form_*Picker*","Car_Reg_Form_Textbox_Owner","Car_Reg_Form_Textbox_Plate" -ValueOnly | ForEach-Object { Confirm-RequiredField -UI_Object $_ }
45 | Confirm-TextPatternField -UI_Object $Car_Reg_Form_Textbox_Plate -Regex '^[0-9]{2}-[0-9]{3}-[0-9]{2}$','^[0-9]{3}-[0-9]{2}-[0-9]{3}$' -ErrorText "Invalid plate number"
46 | Get-Variable -Include "Car_Reg_Form_Combobox*","Car_Reg_Form_*Picker*","Car_Reg_Form_Textbox_Owner","Car_Reg_Form_Textbox_Plate" -ValueOnly | ForEach-Object {
47 | if (Set-ValidationError -UIObject $_ -CheckHasError) {
48 | $FormHasErrors = $true
49 | }
50 | }
51 | if ($FormHasErrors){
52 | return
53 | }
54 |
55 | $RowContent = @(
56 | $Car_Reg_Form_Textbox_Plate.Text
57 | $Car_Reg_Form_Combobox_Make.SelectedItem
58 | $Car_Reg_Form_Combobox_Model.SelectedItem
59 | $Car_Reg_Form_Combobox_Year.SelectedItem
60 | $Car_Reg_Form_Textbox_Owner.Text
61 | $Car_Reg_Form_Combobox_Color.SelectedItem
62 | $Car_Reg_Form_Textbox_Note.Text
63 | $Car_Reg_Form_RatingBar_Rate.Value
64 | $Car_Reg_Form_DatePicker_Registered.Text
65 | $Car_Reg_Form_TimePicker_Registered.Text
66 | )
67 | [void]$Cars_Datatable.Rows.Add($RowContent)
68 | Invoke-Command -Command $OnResetCarForm
69 | Set-NavigationRailTab -NavigationRail $NavRail -TabName "Cars"
70 | })
71 |
72 | $Cars_Datatable = [System.Data.DataTable]::New()
73 | [void]$Cars_Datatable.Columns.AddRange(@('Plate', 'Make', 'Model', 'Year', 'Owner', 'Color', 'Note', 'Rating', 'DateReg', 'TimeReg'))
74 | $Cars_Datatable.primarykey = $Cars_Datatable.columns['Plate']
75 | $Cars_DataGrid.ItemsSource = $Cars_Datatable.DefaultView
76 |
77 | $Cars_Popup_Add_Car.Add_Click({ Set-NavigationRailTab -NavigationRail $NavRail -TabName "CarRegistration" })
78 |
79 | [scriptblock]$OnClosingDrawer = {
80 | $DrawerHost.IsLeftDrawerOpen = $false
81 | $TglBtn_OpenLeftDrawer.IsChecked = $false
82 | $TglBtn_OpenLeftDrawer.Visibility="Visible"
83 | }
84 |
85 | $DrawerHost.add_DrawerClosing($OnClosingDrawer)
86 | $TglBtn_CloseLeftDrawer.add_Click($OnClosingDrawer)
87 |
88 | $TglBtn_OpenLeftDrawer.add_Click({
89 | $DrawerHost.IsLeftDrawerOpen = $true
90 | $TglBtn_CloseLeftDrawer.IsChecked = $true
91 | $TglBtn_OpenLeftDrawer.Visibility="Hidden"
92 | })
93 |
94 | $NavRail.add_SelectionChanged({
95 | if ($_.Source -like "System.Windows.Controls.TabControl*") {
96 | switch (Get-NavigationRailSelectedTabName -NavigationRail $NavRail) {
97 | "Users" { }
98 | "Cars" { }
99 | "CarRegistration" { Invoke-Command -command $OnResetCarForm }
100 | "Photos" { }
101 | "Movies" { }
102 | }
103 | }
104 | })
105 |
106 | $Car_Reg_Form_TextBox_Plate.add_TextChanged( {
107 | Confirm-TextInput -RegexPattern $RegEx_NumbersDash
108 | })
109 |
110 | $Car_Reg_Form_TextBox_Owner.add_TextChanged( {
111 | Confirm-TextInput -RegexPattern $RegEx_LettersSpace -ToUpper
112 | })
113 |
114 | $Car_Reg_Form_Textbox_Note.add_TextChanged( {
115 | Confirm-TextInput -RegexPattern $RegEx_NoteChars
116 | })
117 |
118 | $Car_Reg_Form_TextBox_Plate.add_LostFocus({
119 | Confirm-TextPatternField -Regex '^[0-9]{2}-[0-9]{3}-[0-9]{2}$','^[0-9]{3}-[0-9]{2}-[0-9]{3}$' -ErrorText "Invalid plate number"
120 | })
121 |
122 | $Car_Reg_Form_TimePicker_Registered.add_SelectedTimeChanged({ Confirm-RequiredField })
123 | $Car_Reg_Form_DatePicker_Registered.add_SelectedDateChanged({ Confirm-RequiredField })
124 | Get-Variable -Include "Car_Reg_Form_Combobox*","Car_Reg_Form_TextBox_Owner","Car_Reg_Form_TimePicker_Registered","Car_Reg_Form_DatePicker_Registered" -ValueOnly |
125 | ForEach-Object {$_.add_LostFocus({ Confirm-RequiredField })}
126 | Get-Variable -Include "Car_Reg_Form_TextBox_Plate","Car_Reg_Form_TextBox_Owner" -ValueOnly |
127 | ForEach-Object {$_.add_TextChanged({ Confirm-RequiredField })}
128 |
129 | $Window.ShowDialog() | out-null
--------------------------------------------------------------------------------
/Example9b.xaml:
--------------------------------------------------------------------------------
1 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
60 |
61 |
62 |
63 |
64 |
65 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
141 |
143 |
145 |
146 |
148 |
151 |
152 |
155 |
157 |
158 |
162 |
164 |
166 |
167 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
223 |
226 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # PowerShell WPF apps, based on Material Design style
2 | This repository holds PowerShell scripts, implementing Material Design style for WPF apps.
3 |
4 | They are all part of my blog site https://avicoren.wixsite.com/powershell
5 |
6 | All of the GUI components are based on MDIX project found on this repo:
7 |
8 | https://github.com/MaterialDesignInXAML/MaterialDesignInXamlToolkit
9 |
--------------------------------------------------------------------------------
/Resources/Images/mr_bean.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DrHalfBaked/PowerShell.MaterialDesign/e53a8b2c2e8e28a7c5c40d15fac4cb78b562d00b/Resources/Images/mr_bean.jpg
--------------------------------------------------------------------------------
/Resources/Images/mr_bean_tiny.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DrHalfBaked/PowerShell.MaterialDesign/e53a8b2c2e8e28a7c5c40d15fac4cb78b562d00b/Resources/Images/mr_bean_tiny.jpg
--------------------------------------------------------------------------------
/cars.csv:
--------------------------------------------------------------------------------
1 | Make,Model
2 | Audi,A3
3 | Audi,A5
4 | Audi,Q7
5 | Audi,A4
6 | Nissan,370Z
7 | Maybach,Landaulet
8 | Audi,Q5
9 | Nissan,Cube
10 | Hyundai,Elantra
11 | Nissan,Pathfinder
12 | Infiniti,EX
13 | Infiniti,M
14 | Infiniti,G37
15 | BMW,7
16 | Lotus,Elise
17 | Lotus,Exige
18 | Chevrolet,Silverado
19 | BMW,X5
20 | BMW,X6
21 | Chevrolet,Colorado
22 | Chevrolet,Express
23 | Chevrolet,Silverado
24 | Nissan,370Z
25 | Volvo,C30
26 | Bentley,Brooklands
27 | Bentley,Continental
28 | Volvo,C70
29 | Volvo,S40
30 | Volvo,S80
31 | Volvo,V50
32 | Volvo,XC60
33 | Volvo,XC70
34 | Volvo,XC90
35 | Volvo,V70
36 | Toyota,4Runner
37 | Honda,Accord
38 | Audi,A3
39 | Audi,A4
40 | Toyota,Avalon
41 | Ford,Focus
42 | Nissan,Altima
43 | Toyota,Camry
44 | Bentley,Azure
45 | Rolls-Royce,Ghost
46 | Audi,A5
47 | Rolls-Royce,Phantom
48 | Toyota,Corolla
49 | Volkswagen,Jetta
50 | Toyota,FJ
51 | Toyota,Highlander
52 | Toyota,Land
53 | Maybach,57
54 | Maybach,62
55 | Maybach,Landaulet
56 | Toyota,Matrix
57 | Volkswagen,CC
58 | Audi,A6
59 | Nissan,Armada
60 | Audi,A8
61 | Nissan,Cube
62 | Audi,Q5
63 | Lamborghini,Gallardo
64 | Chevrolet,Aveo5
65 | Lexus,LS
66 | Hyundai,Accent
67 | Hyundai,Azera
68 | Audi,Q7
69 | Mercedes-Benz,C-Class
70 | BMW,1
71 | Hyundai,Elantra
72 | Ford,Fusion
73 | Kia,Forte
74 | Honda,Civic
75 | Kia,Optima
76 | Hyundai,Genesis
77 | Volkswagen,GTI
78 | Kia,Rio5
79 | Kia,Rio
80 | Ford,Mustang
81 | Kia,Soul
82 | Audi,R8
83 | Kia,Sedona
84 | Chevrolet,Camaro
85 | Volkswagen,Golf
86 | Audi,S4
87 | Kia,Sportage
88 | Hyundai,Santa
89 | Ford,Taurus
90 | Ford,Edge
91 | Audi,S5
92 | Audi,S6
93 | Chevrolet,Corvette
94 | Nissan,Pathfinder
95 | Volkswagen,Routan
96 | Volkswagen,Tiguan
97 | Hyundai,Sonata
98 | Hyundai,Veracruz
99 | Honda,Fit
100 | Mazda,CX-7
101 | Ford,Flex
102 | Volkswagen,Touareg
103 | Mercedes-Benz,CL-Class
104 | Hyundai,Tucson
105 | Mercedes-Benz,CLS-Class
106 | Mitsubishi,Eclipse
107 | Toyota,RAV4
108 | Mitsubishi,Endeavor
109 | Mitsubishi,Galant
110 | Mitsubishi,Lancer
111 | Cadillac,CTS-V
112 | Cadillac,CTS
113 | BMW,3
114 | Infiniti,EX
115 | Mercedes-Benz,E-Class
116 | Mercedes-Benz,G-Class
117 | Mitsubishi,Outlander
118 | Toyota,Sequoia
119 | Mercedes-Benz,GL-Class
120 | Nissan,Sentra
121 | Nissan,Versa
122 | Mercedes-Benz,GLK-Class
123 | Mercedes-Benz,R-Class
124 | Ford,Escape
125 | Cadillac,Escalade
126 | Dodge,Avenger
127 | Honda,CR-V
128 | Cadillac,DTS
129 | Cadillac,SRX
130 | Nissan,Xterra
131 | BMW,5
132 | Mercedes-Benz,M-Class
133 | Mercedes-Benz,SLK-Class
134 | Lincoln,MKS
135 | Lincoln,MKT
136 | Lincoln,MKX
137 | Lincoln,MKZ
138 | Mazda,CX-9
139 | Toyota,Sienna
140 | Honda,Element
141 | Mazda,Mazda3
142 | Mazda,Mazdaspeed3
143 | Ford,Explorer
144 | Mazda,Mazda5
145 | Lincoln,Navigator
146 | Lincoln,Town
147 | Infiniti,FX
148 | Dodge,Caliber
149 | BMW,6
150 | Infiniti,M
151 | Dodge,Challenger
152 | Cadillac,STS
153 | Mazda,Mazda6
154 | Dodge,Charger
155 | Ford,Expedition
156 | Mazda,MX-5
157 | Mazda,RX-8
158 | Toyota,Venza
159 | Toyota,Yaris
160 | Transit,Connect
161 | Ford,Crown
162 | Mazda,Tribute
163 | Jeep,Commander
164 | GMC,Acadia
165 | GMC,Terrain
166 | GMC,Canyon
167 | Infiniti,G37
168 | Honda,Pilot
169 | Dodge,Grand
170 | Jeep,Compass
171 | BMW,7
172 | Chevrolet,Equinox
173 | Dodge,Journey
174 | Lexus,ES
175 | Dodge,Nitro
176 | Porsche,911
177 | GMC,Yukon
178 | Infiniti,QX56
179 | Acura,MDX
180 | Acura,RDX
181 | BMW,M3
182 | Acura,ZDX
183 | Acura,RL
184 | Acura,TL
185 | Acura,TSX
186 | Dodge,Viper
187 | Porsche,Boxster
188 | Porsche,Cayenne
189 | Chevrolet,HHR
190 | Porsche,Cayman
191 | Chevrolet,Impala
192 | Buick,Enclave
193 | Buick,Lacrosse
194 | Suzuki,Grand
195 | GMC,Sierra
196 | Honda,Odyssey
197 | GMC,Savana
198 | Suzuki,Kizashi
199 | Saab,09-Mar
200 | Suzuki,SX4
201 | Subaru,Forester
202 | Lexus,GS
203 | Buick,Lucerne
204 | Aston,Martin
205 | Subaru,Impreza
206 | Jeep,Grand
207 | Land,Rover
208 | Jeep,Liberty
209 | Ferrari,612
210 | Chrysler,Sebring
211 | Scion,tC
212 | MINI,Cooper
213 | MINI,Clubman
214 | Jaguar,XK
215 | Chrysler,300
216 | Chrysler,Town
217 | Jaguar,XF
218 | Jeep,Patriot
219 | Lotus,Elise
220 | Chevrolet,Malibu
221 | Lotus,Exige
222 | Maserati,GranTurismo
223 | Jeep,Wrangler
224 | Maserati,Quattroporte
225 | Honda,Ridgeline
226 | Mercury,Grand
227 | BMW,M6
228 | BMW,X3
229 | Chevrolet,Suburban
230 | Chevrolet,Tahoe
231 | BMW,Z4
232 | Saab,09-May
233 | Mercury,Mariner
234 | Chevrolet,Traverse
235 | Mercury,Milan
236 | Chevrolet,Avalanche
237 | Dodge,Ram
238 | Lexus,IS
239 | Toyota,Tacoma
240 | Scion,xB
241 | Scion,xD
242 | Jaguar,XJ
243 | Subaru,Legacy
244 | Suzuki,Equator
245 | Subaru,Outback
246 | Nissan,Frontier
247 | Lexus,LX
248 | Ford,Ranger
249 | Toyota,Tundra
250 | Dodge,Dakota
251 | Nissan,Titan
252 | Ford,F-150
253 | BMW,X5
254 | BMW,X6
255 | Chevrolet,Colorado
256 | Chevrolet,Express
257 | Chevrolet,Silverado
258 | Nissan,370Z
259 | Volvo,C30
260 | Bentley,Continental
261 | Volvo,C70
262 | Volvo,S40
263 | Volvo,S60
264 | Volvo,S80
265 | Volvo,V50
266 | Volvo,XC60
267 | Volvo,XC70
268 | Toyota,4Runner
269 | Volvo,XC90
270 | Audi,A3
271 | Audi,A4
272 | Ford,Fiesta
273 | Honda,Accord
274 | Toyota,Avalon
275 | Toyota,Camry
276 | Ford,Focus
277 | Nissan,Altima
278 | Toyota,Corolla
279 | Audi,A5
280 | Rolls-Royce,Ghost
281 | Rolls-Royce,Phantom
282 | Volkswagen,Jetta
283 | Toyota,FJ
284 | Audi,A6
285 | Toyota,Highlander
286 | Toyota,Land
287 | Toyota,Matrix
288 | Maybach,57
289 | Maybach,62
290 | Maybach,Landaulet
291 | Nissan,Armada
292 | Chevrolet,Aveo
293 | Chevrolet,Aveo5
294 | Audi,A8
295 | Nissan,Cube
296 | Audi,Q5
297 | Honda,Civic
298 | Lamborghini,Gallardo
299 | Lexus,LS
300 | Hyundai,Accent
301 | Hyundai,Azera
302 | Audi,Q7
303 | Toyota,RAV4
304 | Nissan,Juke
305 | Chevrolet,Camaro
306 | Hyundai,Elantra
307 | Volkswagen,CC
308 | Ford,Fusion
309 | Kia,Forte
310 | Audi,R8
311 | Hyundai,Equus
312 | Kia,Optima
313 | Kia,Rio
314 | Hyundai,Genesis
315 | Volkswagen,GTI
316 | Ford,Mustang
317 | Mercedes-Benz,C-Class
318 | Kia,Rio5
319 | Kia,Soul
320 | Ford,Shelby
321 | Kia,Sedona
322 | Audi,S4
323 | Kia,Sorento
324 | Kia,Sportage
325 | Nissan,Pathfinder
326 | Hyundai,Santa
327 | Ford,Taurus
328 | Volkswagen,Golf
329 | Ford,Edge
330 | Audi,S5
331 | Audi,S6
332 | Chevrolet,Corvette
333 | Volkswagen,Routan
334 | Hyundai,Sonata
335 | Honda,CR-Z
336 | Hyundai,Veracruz
337 | Honda,Fit
338 | Mazda,CX-7
339 | Ford,Flex
340 | Hyundai,Tucson
341 | Mazda,CX-9
342 | Volkswagen,Tiguan
343 | BMW,1
344 | Mercedes-Benz,CL-Class
345 | Mercedes-Benz,CLS-Class
346 | Mitsubishi,Eclipse
347 | Mitsubishi,Endeavor
348 | Mitsubishi,Galant
349 | Cadillac,CTS-V
350 | Mitsubishi,Lancer
351 | Cadillac,CTS
352 | Toyota,Sequoia
353 | Mercedes-Benz,E-Class
354 | BMW,3
355 | Nissan,Sentra
356 | Mercedes-Benz,G-Class
357 | Cadillac,Escalade
358 | Mitsubishi,Outlander
359 | Cadillac,DTS
360 | Infiniti,EX
361 | Mercedes-Benz,GL-Class
362 | Nissan,Versa
363 | Mercedes-Benz,GLK-Class
364 | Ford,Escape
365 | Mercedes-Benz,R-Class
366 | Chevrolet,Cruze
367 | Cadillac,SRX
368 | Dodge,Avenger
369 | Honda,CR-V
370 | Honda,Element
371 | Nissan,Xterra
372 | Mercedes-Benz,M-Class
373 | Toyota,Sienna
374 | BMW,5
375 | Mercedes-Benz,SL-Class
376 | Mercedes-Benz,SLK-Class
377 | Lincoln,MKS
378 | Lincoln,MKT
379 | Lincoln,MKX
380 | Lincoln,MKZ
381 | Mazda,Mazda2
382 | Mazda,Mazda3
383 | Ford,Explorer
384 | Mazda,Mazdaspeed3
385 | Honda,Pilot
386 | Lincoln,Navigator
387 | Lincoln,Town
388 | Infiniti,FX
389 | Cadillac,STS
390 | Dodge,Caliber
391 | Dodge,Challenger
392 | Infiniti,M
393 | Toyota,Venza
394 | Ford,Expedition
395 | Dodge,Charger
396 | Mazda,Mazda6
397 | GMC,Acadia
398 | Dodge,Durango
399 | Mazda,MX-5
400 | Mazda,RX-8
401 | Infiniti,G25
402 | Toyota,Yaris
403 | Chevrolet,Equinox
404 | Transit,Connect
405 | Porsche,911
406 | Mazda,Tribute
407 | Dodge,Grand
408 | Jeep,Compass
409 | GMC,Canyon
410 | Dodge,Journey
411 | Infiniti,G37
412 | BMW,7
413 | BMW,ActiveHybrid
414 | Dodge,Nitro
415 | BMW,ALPINA
416 | Infiniti,IPL
417 | GMC,Terrain
418 | GMC,Yukon
419 | Infiniti,QX56
420 | Acura,MDX
421 | Acura,RDX
422 | Acura,ZDX
423 | BMW,M3
424 | Acura,RL
425 | Acura,TL
426 | Acura,TSX
427 | GMC,Savana
428 | Porsche,Boxster
429 | Porsche,Cayenne
430 | Chevrolet,HHR
431 | Porsche,Cayman
432 | Chevrolet,Impala
433 | Subaru,Forester
434 | Buick,Enclave
435 | Suzuki,Grand
436 | Buick,Lacrosse
437 | Honda,Odyssey
438 | Suzuki,Kizashi
439 | Saab,09-Mar
440 | Suzuki,SX4
441 | Lexus,ES
442 | Buick,Lucerne
443 | Buick,Regal
444 | Aston,Martin
445 | Jeep,Grand
446 | Subaru,Impreza
447 | Jeep,Liberty
448 | Land,Rover
449 | Chrysler,200
450 | Scion,tC
451 | MINI,Cooper
452 | Jaguar,XJ
453 | MINI,Clubman
454 | Jaguar,XK
455 | Chrysler,300
456 | Jaguar,XF
457 | Jeep,Patriot
458 | Chrysler,Town
459 | Lotus,Elise
460 | Chevrolet,Malibu
461 | Lotus,Evora
462 | MINI,Countryman
463 | Lotus,Exige
464 | Maserati,GranTurismo
465 | Maserati,Quattroporte
466 | Jeep,Wrangler
467 | Honda,Ridgeline
468 | Mercury,Grand
469 | Mercury,Mariner
470 | BMW,X3
471 | Chevrolet,Suburban
472 | Dodge,Ram
473 | GMC,Sierra
474 | Chevrolet,Tahoe
475 | BMW,Z4
476 | Saab,9-4X
477 | Saab,09-May
478 | Chevrolet,Traverse
479 | Mercury,Milan
480 | Lexus,GS
481 | Chevrolet,Avalanche
482 | Subaru,Legacy
483 | Lexus,IS
484 | Toyota,Tacoma
485 | Scion,xB
486 | Scion,xD
487 | Toyota,Tundra
488 | Suzuki,Equator
489 | Nissan,Frontier
490 | Subaru,Outback
491 | Ford,Ranger
492 | Lexus,LX
493 | Ford,E-150
494 | Ford,E-350
495 | Dodge,Dakota
496 | Nissan,Titan
497 | Ford,E-250
498 | Ford,F-150
499 | Acura,TL
500 | Chevrolet,Colorado
501 | Chevrolet,Express
502 | Bentley,Continental
503 | Volvo,S60
504 | Audi,A3
505 | Audi,A4
506 | Ford,Fiesta
507 | Ford,Focus
508 | Volvo,S80
509 | Volvo,XC60
510 | Volvo,XC70
511 | Volvo,XC90
512 | Audi,A5
513 | Audi,A6
514 | Audi,A7
515 | Audi,Q5
516 | Audi,Q7
517 | Hyundai,Accent
518 | Chevrolet,Camaro
519 | Hyundai,Elantra
520 | Ford,Fusion
521 | Audi,R8
522 | Hyundai,Genesis
523 | Ford,Mustang
524 | Kia,Sedona
525 | Kia,Sorento
526 | Audi,S4
527 | Kia,Sportage
528 | Ford,Taurus
529 | Audi,S5
530 | Ford,Edge
531 | Chevrolet,Corvette
532 | Hyundai,Sonata
533 | Hyundai,Tucson
534 | Ford,Flex
535 | Mitsubishi,Eclipse
536 | Ford,Escape
537 | Chevrolet,Cruze
538 | Nissan,Altima
539 | Nissan,Sentra
540 | Nissan,Versa
541 | Ford,Explorer
542 | Mazda,Mazda5
543 | Mazda,Mazda6
544 | Infiniti,M
545 | Chevrolet,Equinox
546 | Ford,Transit
547 | Toyota,Yaris
548 | Toyota,Highlander
549 | Chevrolet,Impala
550 | Subaru,Impreza
551 | Land,Rover
552 | Scion,tC
553 | MINI,Cooper
554 | Chevrolet,Malibu
555 | MINI,Clubman
556 | MINI,Countryman
557 | Chevrolet,Sonic
558 | Toyota,Camry
559 | Toyota,FJ
560 | Chevrolet,Traverse
561 | Scion,xB
562 | Aston,Martin
563 | Ford,E-150
564 | Buick,Enclave
565 | Ford,E-350
566 | Buick,Lacrosse
567 | Buick,Regal
568 | Ford,E-250
569 | Nissan,Titan
570 | BMW,1
571 | BMW,3
572 | Nissan,370Z
573 | Nissan,JUKE
574 | Hyundai,Veloster
575 | Hyundai,Equus
576 | Hyundai,Santa
577 | Ford,Expedition
578 | Nissan,Xterra
579 | Nissan,Pathfinder
580 | Hyundai,Veracruz
581 | Infiniti,G25
582 | Infiniti,G37
583 | Volvo,C30
584 | Jeep,Compass
585 | Nissan,Armada
586 | Lexus,IS
587 | Lexus,ES
588 | Lexus,LS
589 | Toyota,Sienna
590 | Audi,A8
591 | Audi,TT
592 | Honda,Accord
593 | Lexus,RX
594 | Infiniti,IPL
595 | Lexus,LFA
596 | Infiniti,EX
597 | Infiniti,FX
598 | Infiniti,QX56
599 | Dodge,Durango
600 | Jeep,Grand
601 | Toyota,4Runner
602 | Mazda,Mazda2
603 | Toyota,Sequoia
604 | Mazda,Mazda3
605 | Dodge,Charger
606 | Volkswagen,Tiguan
607 | Dodge,Challenger
608 | Dodge,Avenger
609 | Dodge,Caliber
610 | Volkswagen,Jetta
611 | Volkswagen,CC
612 | Mazda,Mazdaspeed3
613 | Dodge,Grand
614 | Mazda,MX-5
615 | Dodge,Journey
616 | Mazda,CX-9
617 | Kia,Forte
618 | Honda,Civic
619 | Kia,Optima
620 | Kia,Rio
621 | Kia,Soul
622 | Volkswagen,Passat
623 | Volkswagen,Touareg
624 | GMC,Acadia
625 | GMC,Terrain
626 | GMC,Yukon
627 | Volvo,C70
628 | GMC,Savana
629 | Volkswagen,Golf
630 | Cadillac,CTS
631 | Jaguar,XF
632 | Jaguar,XJ
633 | Jaguar,XK
634 | Jeep,Liberty
635 | Cadillac,CTS-V
636 | Volkswagen,Routan
637 | Volkswagen,GTI
638 | Jeep,Patriot
639 | Volkswagen,Beetle
640 | Jeep,Wrangler
641 | Cadillac,SRX
642 | Cadillac,Escalade
643 | BMW,5
644 | Acura,RL
645 | Acura,TSX
646 | Acura,ZDX
647 | Acura,MDX
648 | Subaru,Legacy
649 | Mitsubishi,Galant
650 | Mitsubishi,Outlander
651 | Subaru,Outback
652 | Buick,Verano
653 | Suzuki,Kizashi
654 | Saab,09-Mar
655 | Subaru,Forester
656 | Suzuki,SX4
657 | Lincoln,MKZ
658 | Lincoln,MKS
659 | Lincoln,MKX
660 | Lincoln,MKT
661 | Bentley,Mulsanne
662 | Lincoln,Navigator
663 | Honda,CR-Z
664 | Honda,Fit
665 | Honda,Odyssey
666 | Honda,Pilot
667 | Lamborghini,Gallardo
668 | BMW,7
669 |
--------------------------------------------------------------------------------