├── wpf-controlexplorer.gif ├── README.md ├── LICENSE └── WPF-ControlExplorer.ps1 /wpf-controlexplorer.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SMSAgentSoftware/WPF-Control-Explorer/HEAD/wpf-controlexplorer.gif -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # WPF-Control-Explorer 2 | WPF Control Explorer is a simple tool that allows you to explore the various built-in controls used in creating WPF desktop applications. The various properties, methods and events of each control can be easily discovered, together with the relevant .Net class name, member definitions and any static members that may be available on the properties. 3 | 4 | The tool is a useful quick-reference when creating WPF applications, and can also be used to learn the various members of the native WPF controls. 5 | 6 | More details on my blog: https://smsagent.blog/tools/wpf-control-explorer/ 7 | 8 | ![Screenshot](https://raw.githubusercontent.com/SMSAgentSoftware/WPF-Control-Explorer/master/wpf-controlexplorer.gif) 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Trevor Jones 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /WPF-ControlExplorer.ps1: -------------------------------------------------------------------------------- 1 | ########################################################################## 2 | ## WPF CONTROL EXPLORER ## 3 | ## v1.0 ## 4 | ## Author: Trevor Jones ## 5 | ## Released: 26-Sep-2016 ## 6 | ## More Info: http://smsagent.wordpress.com/tools/wpf-control-explorer/ ## 7 | ########################################################################## 8 | 9 | <# 10 | .Synopsis 11 | Exposes the properties, methods and events of the built-in WPF controls commonly used in WPF Windows desktop applications 12 | .Notes 13 | Do not run from an existing PowerShell console session as the script will close it. Right-click the script and run with PowerShell. 14 | #> 15 | 16 | #region UserInterface 17 | # Load Assemblies 18 | Add-Type -AssemblyName PresentationFramework 19 | 20 | # Define XAML code 21 | [xml]$xaml = @" 22 | 26 | 27 | 28 | 29 | 34 | 35 | 36 | 41 | 42 | 43 | 71 | 72 | 73 | "@ 74 | 75 | # Load XAML elements into a hash table 76 | $script:hash = [hashtable]::Synchronized(@{}) 77 | $hash.Window = [Windows.Markup.XamlReader]::Load((New-Object -TypeName System.Xml.XmlNodeReader -ArgumentList $xaml)) 78 | $xaml.SelectNodes("//*[@*[contains(translate(name(.),'n','N'),'Name')]]") | ForEach-Object -Process { 79 | $hash.$($_.Name) = $hash.Window.FindName($_.Name) 80 | } 81 | #endregion 82 | 83 | 84 | 85 | #region PopulateInitialData 86 | # Define the list of controls 87 | $Controls = @( 88 | "Border", 89 | "Button", 90 | "Calendar", 91 | "Canvas", 92 | "CheckBox", 93 | "ComboBox", 94 | "ContentControl", 95 | "DataGrid", 96 | "DatePicker", 97 | "DockPanel", 98 | "DocumentViewer", 99 | "Ellipse", 100 | "Expander", 101 | "Grid", 102 | "GridSplitter", 103 | "GroupBox", 104 | "Image", 105 | "Label", 106 | "ListBox", 107 | "ListView", 108 | "MediaElement", 109 | "Menu", 110 | "NavigationWindow", 111 | "PasswordBox", 112 | "ProgressBar", 113 | "RadioButton", 114 | "Rectangle", 115 | "RichTextBox", 116 | "ScrollBar", 117 | "ScrollViewer", 118 | "Separator", 119 | "Slider", 120 | "StackPanel", 121 | "StatusBar", 122 | "TabControl", 123 | "TextBlock", 124 | "TextBox", 125 | "ToolBar", 126 | "ToolBarPanel", 127 | "ToolBarTray", 128 | "TreeView", 129 | "ViewBox", 130 | "WebBrowser", 131 | "Window", 132 | "WrapPanel" 133 | ) 134 | 135 | # Define the list of member types 136 | $Members = @("Property","Method","Event") 137 | 138 | # Load the .Net type names in the current domain and filter for controls in the WPF 139 | $ControlTypes = [AppDomain]::CurrentDomain.GetAssemblies() | foreach {$_.GetTypes()} | where {$_.Name -in $Controls -and $_.Module -match "PresentationFramework.dll"}| Select Name,FullName 140 | 141 | # Populate the combo boxes with controls and member types 142 | $Hash.CB_Control.ItemsSource = [array]$Controls 143 | $Hash.CB_Member.ItemsSource = [array]$Members 144 | #endregion 145 | 146 | 147 | 148 | #region Event Handling 149 | # When selection changed on the Control combobox 150 | $Hash.CB_Control.Add_SelectionChanged({ 151 | # Blank everything 152 | $Hash.CB_Member.SelectedValue = '' 153 | $Hash.LB_Member.ItemsSource = '' 154 | $Hash.TB_Definition.Text = '' 155 | $Hash.LB_Static.ItemsSource = '' 156 | $Hash.TB_Filter.Text = '' 157 | $Hash.TB_MemberCount.Text = '' 158 | # Populate the .Net class textblock 159 | $DotNetClass = $ControlTypes | Where {$_.Name -eq $This.SelectedItem} | Select -ExpandProperty FullName 160 | $Hash.TB_Class.Text = $DotNetClass 161 | }) 162 | 163 | # When selection changed on the Member combobox 164 | $Hash.CB_Member.Add_SelectionChanged({ 165 | $Hash.TB_Filter.Text = '' 166 | # Only run if something has been selected 167 | If ($This.SelectedIndex -ne "-1") 168 | { 169 | # Create a control of the selected type 170 | $ControlType = $ControlTypes | Where {$_.Name -eq $hash.CB_Control.SelectedItem} 171 | $Control = New-Object ($ControlType.FullName) 172 | # Find and populate the members of the selected member type 173 | $script:Members = $Control | Get-Member -MemberType $This.SelectedItem -Force | Select Name,Definition 174 | $Hash.LB_Member.ItemsSource = [array]$Members.Name 175 | $Hash.TB_MemberCount.Text = $Members.Count 176 | # If 'method', enable the methods stackpanel in the filter section 177 | If ($This.SelectedItem -eq "Method") 178 | { 179 | $Hash.SP_Methods.IsEnabled = $True 180 | $Hash.CB_all.IsChecked = $True 181 | } 182 | Else 183 | { 184 | $Hash.SP_Methods.IsEnabled = $False 185 | $hash.CB_all.IsChecked = $False 186 | } 187 | # Make sure the checkboxes are not checked 188 | $Hash.CB_add.IsChecked = $False 189 | $Hash.CB_remove.IsChecked = $False 190 | $Hash.CB_set.IsChecked = $False 191 | $Hash.CB_NoUnderscore.IsChecked = $False 192 | $Hash.CB_get.IsChecked = $False 193 | } 194 | 195 | }) 196 | 197 | # When selection changed on Member listbox 198 | $Hash.LB_Member.Add_SelectionChanged({ 199 | # Find the definition and populate the definition textbox 200 | $Definition = $Members | where {$_.Name -eq $This.SelectedItem} | Select -ExpandProperty Definition 201 | $Hash.TB_Definition.Text = $Definition 202 | # If 'property', we need to get the static members also, where available 203 | If ($Hash.CB_Member.SelectedItem -eq "Property") 204 | { 205 | $script:StaticMembers = '' 206 | # Only run if the definition contains something in the System namespace 207 | If ($Definition -match 'System.') 208 | { 209 | $ClassName = $Definition.Split(' ')[0] 210 | try 211 | { 212 | # Get the list of static member names 213 | $script:StaticMembers = New-Object -TypeName $ClassName -ErrorAction Stop | Get-Member -Static -MemberType Property -ErrorAction Stop | Select -ExpandProperty Name 214 | } 215 | catch 216 | { 217 | $Hash.LB_Static.ItemsSource = "" 218 | } 219 | if ($StaticMembers -ne "Empty") 220 | { 221 | # Populate the static list box with the static members 222 | $Hash.LB_Static.ItemsSource = [array]$StaticMembers 223 | } 224 | } 225 | Else 226 | { 227 | $Hash.LB_Static.ItemsSource = "" 228 | } 229 | } 230 | Else 231 | { 232 | $Hash.LB_Static.ItemsSource = "" 233 | } 234 | }) 235 | 236 | # When the filter textbox is used 237 | $Hash.TB_Filter.Add_TextChanged({ 238 | [System.Windows.Data.CollectionViewSource]::GetDefaultView($Hash.LB_Member.ItemsSource).Filter = [Predicate[Object]]{ 239 | Try { 240 | $args[0] -match [regex]::Escape($This.Text) 241 | } Catch { 242 | $True 243 | } 244 | } 245 | }) 246 | 247 | #region Checkbox event handling 248 | # If checkbox checked, uncheck the other checkboxes, and populate the member list box based on the checkbox selections 249 | $Hash.CB_all.Add_Checked({ 250 | $hash.CB_add.IsChecked = $False 251 | $Hash.CB_remove.IsChecked = $False 252 | $Hash.CB_set.IsChecked = $False 253 | $Hash.CB_NoUnderscore.IsChecked = $False 254 | $Hash.CB_get.IsChecked = $False 255 | $Hash.TB_Filter.Text = '' 256 | 257 | $Hash.LB_Member.ItemsSource = [array]$Members.Name 258 | }) 259 | 260 | $Hash.CB_add.Add_Checked({ 261 | $hash.CB_all.IsChecked = $False 262 | $Hash.CB_remove.IsChecked = $False 263 | $Hash.CB_set.IsChecked = $False 264 | $Hash.CB_NoUnderscore.IsChecked = $False 265 | $Hash.CB_get.IsChecked = $False 266 | $Hash.TB_Filter.Text = '' 267 | 268 | $Hash.LB_Member.ItemsSource = [array]($Members | where {$_ -match "add_"} | Select -ExpandProperty Name) 269 | }) 270 | 271 | $Hash.CB_get.Add_Checked({ 272 | $hash.CB_all.IsChecked = $False 273 | $Hash.CB_remove.IsChecked = $False 274 | $Hash.CB_set.IsChecked = $False 275 | $Hash.CB_NoUnderscore.IsChecked = $False 276 | $Hash.CB_add.IsChecked = $False 277 | $Hash.TB_Filter.Text = '' 278 | 279 | $Hash.LB_Member.ItemsSource = [array]($Members | where {$_ -match "get_"} | Select -ExpandProperty Name) 280 | }) 281 | 282 | $Hash.CB_remove.Add_Checked({ 283 | $hash.CB_all.IsChecked = $False 284 | $Hash.CB_get.IsChecked = $False 285 | $Hash.CB_set.IsChecked = $False 286 | $Hash.CB_NoUnderscore.IsChecked = $False 287 | $Hash.CB_add.IsChecked = $False 288 | $Hash.TB_Filter.Text = '' 289 | 290 | $Hash.LB_Member.ItemsSource = [array]($Members | where {$_ -match "remove_"} | Select -ExpandProperty Name) 291 | }) 292 | 293 | $Hash.CB_set.Add_Checked({ 294 | $hash.CB_all.IsChecked = $False 295 | $Hash.CB_get.IsChecked = $False 296 | $Hash.CB_remove.IsChecked = $False 297 | $Hash.CB_NoUnderscore.IsChecked = $False 298 | $Hash.CB_add.IsChecked = $False 299 | $Hash.TB_Filter.Text = '' 300 | 301 | $Hash.LB_Member.ItemsSource = [array]($Members | where {$_ -match "set_"} | Select -ExpandProperty Name) 302 | }) 303 | 304 | $Hash.CB_NoUnderscore.Add_Checked({ 305 | $hash.CB_all.IsChecked = $False 306 | $Hash.CB_get.IsChecked = $False 307 | $Hash.CB_remove.IsChecked = $False 308 | $Hash.CB_set.IsChecked = $False 309 | $Hash.CB_add.IsChecked = $False 310 | $Hash.TB_Filter.Text = '' 311 | 312 | $Hash.LB_Member.ItemsSource = [array]($Members | where {$_ -notmatch "_"} | Select -ExpandProperty Name) 313 | }) 314 | 315 | # Create Unchecked events to restore all results if a checkbox gets unchecked, and clear the text filter 316 | $hash.CB_NoUnderscore,$Hash.CB_get,$Hash.CB_remove,$Hash.CB_set,$Hash.CB_add | foreach { 317 | $_.Add_UnChecked({ 318 | If ($hash.CB_NoUnderscore.IsChecked -ne $True -and $hash.CB_get.IsChecked -ne $True -and $hash.CB_remove.IsChecked -ne $True -and $hash.CB_set.IsChecked -ne $True -and $hash.CB_add.IsChecked -ne $True) 319 | { 320 | $Hash.CB_all.IsChecked = $True 321 | $Hash.TB_Filter.Text = '' 322 | } 323 | }) 324 | } 325 | #endregion 326 | #endregion 327 | 328 | 329 | 330 | #region Display the UI 331 | # Display Window 332 | # If code is running in ISE, use ShowDialog()... 333 | if ($psISE) 334 | { 335 | $null = $Hash.window.Dispatcher.InvokeAsync{$Hash.Window.ShowDialog()}.Wait() 336 | } 337 | # ...otherwise run as an application 338 | Else 339 | { 340 | # Make PowerShell Disappear 341 | $windowcode = '[DllImport("user32.dll")] public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);' 342 | $asyncwindow = Add-Type -MemberDefinition $windowcode -Name Win32ShowWindowAsync -Namespace Win32Functions -PassThru 343 | $null = $asyncwindow::ShowWindowAsync((Get-Process -PID $pid).MainWindowHandle, 0) 344 | 345 | $app = New-Object -TypeName Windows.Application 346 | $app.Run($Hash.Window) 347 | } 348 | #endregion --------------------------------------------------------------------------------