function Initialize-UIControls { param([PSCustomObject]$State) WriteLog "Initializing UI control references..." $window = $State.Window # Find all controls ONCE and store them in the state object $State.Controls.cmbWindowsRelease = $window.FindName('cmbWindowsRelease') $State.Controls.cmbWindowsVersion = $window.FindName('cmbWindowsVersion') $State.Controls.txtISOPath = $window.FindName('txtISOPath') $State.Controls.btnBrowseISO = $window.FindName('btnBrowseISO') $State.Controls.cmbWindowsArch = $window.FindName('cmbWindowsArch') $State.Controls.cmbWindowsLang = $window.FindName('cmbWindowsLang') $State.Controls.cmbWindowsSKU = $window.FindName('cmbWindowsSKU') $State.Controls.cmbMediaType = $window.FindName('cmbMediaType') $State.Controls.txtOptionalFeatures = $window.FindName('txtOptionalFeatures') $State.Controls.featuresPanel = $window.FindName('stackFeaturesContainer') $State.Controls.chkDownloadDrivers = $window.FindName('chkDownloadDrivers') $State.Controls.cmbMake = $window.FindName('cmbMake') $State.Controls.spMakeSection = $window.FindName('spMakeSection') $State.Controls.btnGetModels = $window.FindName('btnGetModels') $State.Controls.spModelFilterSection = $window.FindName('spModelFilterSection') $State.Controls.txtModelFilter = $window.FindName('txtModelFilter') $State.Controls.lstDriverModels = $window.FindName('lstDriverModels') $State.Controls.spDriverActionButtons = $window.FindName('spDriverActionButtons') $State.Controls.btnSaveDriversJson = $window.FindName('btnSaveDriversJson') $State.Controls.btnImportDriversJson = $window.FindName('btnImportDriversJson') $State.Controls.btnDownloadSelectedDrivers = $window.FindName('btnDownloadSelectedDrivers') $State.Controls.btnClearDriverList = $window.FindName('btnClearDriverList') $State.Controls.chkInstallOffice = $window.FindName('chkInstallOffice') $State.Controls.chkInstallApps = $window.FindName('chkInstallApps') $State.Controls.OfficePathStackPanel = $window.FindName('OfficePathStackPanel') $State.Controls.OfficePathGrid = $window.FindName('OfficePathGrid') $State.Controls.CopyOfficeConfigXMLStackPanel = $window.FindName('CopyOfficeConfigXMLStackPanel') $State.Controls.OfficeConfigurationXMLFileStackPanel = $window.FindName('OfficeConfigurationXMLFileStackPanel') $State.Controls.OfficeConfigurationXMLFileGrid = $window.FindName('OfficeConfigurationXMLFileGrid') $State.Controls.chkCopyOfficeConfigXML = $window.FindName('chkCopyOfficeConfigXML') $State.Controls.chkLatestCU = $window.FindName('chkUpdateLatestCU') $State.Controls.chkPreviewCU = $window.FindName('chkUpdatePreviewCU') $State.Controls.btnCheckUSBDrives = $window.FindName('btnCheckUSBDrives') $State.Controls.lstUSBDrives = $window.FindName('lstUSBDrives') $State.Controls.chkSelectAllUSBDrives = $window.FindName('chkSelectAllUSBDrives') $State.Controls.chkBuildUSBDriveEnable = $window.FindName('chkBuildUSBDriveEnable') $State.Controls.usbSection = $window.FindName('usbDriveSection') $State.Controls.chkSelectSpecificUSBDrives = $window.FindName('chkSelectSpecificUSBDrives') $State.Controls.usbSelectionPanel = $window.FindName('usbDriveSelectionPanel') $State.Controls.chkAllowExternalHardDiskMedia = $window.FindName('chkAllowExternalHardDiskMedia') $State.Controls.chkPromptExternalHardDiskMedia = $window.FindName('chkPromptExternalHardDiskMedia') $State.Controls.chkInstallWingetApps = $window.FindName('chkInstallWingetApps') $State.Controls.wingetPanel = $window.FindName('wingetPanel') $State.Controls.btnCheckWingetModule = $window.FindName('btnCheckWingetModule') $State.Controls.txtWingetVersion = $window.FindName('txtWingetVersion') $State.Controls.txtWingetModuleVersion = $window.FindName('txtWingetModuleVersion') $State.Controls.applicationPathPanel = $window.FindName('applicationPathPanel') $State.Controls.appListJsonPathPanel = $window.FindName('appListJsonPathPanel') $State.Controls.btnBrowseApplicationPath = $window.FindName('btnBrowseApplicationPath') $State.Controls.btnBrowseAppListJsonPath = $window.FindName('btnBrowseAppListJsonPath') $State.Controls.chkBringYourOwnApps = $window.FindName('chkBringYourOwnApps') $State.Controls.byoApplicationPanel = $window.FindName('byoApplicationPanel') $State.Controls.wingetSearchPanel = $window.FindName('wingetSearchPanel') $State.Controls.txtWingetSearch = $window.FindName('txtWingetSearch') $State.Controls.btnWingetSearch = $window.FindName('btnWingetSearch') $State.Controls.lstWingetResults = $window.FindName('lstWingetResults') $State.Controls.btnSaveWingetList = $window.FindName('btnSaveWingetList') $State.Controls.btnImportWingetList = $window.FindName('btnImportWingetList') $State.Controls.btnClearWingetList = $window.FindName('btnClearWingetList') $State.Controls.btnDownloadSelected = $window.FindName('btnDownloadSelected') $State.Controls.btnBrowseAppSource = $window.FindName('btnBrowseAppSource') $State.Controls.btnBrowseFFUDevPath = $window.FindName('btnBrowseFFUDevPath') $State.Controls.btnBrowseFFUCaptureLocation = $window.FindName('btnBrowseFFUCaptureLocation') $State.Controls.btnBrowseOfficePath = $window.FindName('btnBrowseOfficePath') $State.Controls.btnBrowseDriversFolder = $window.FindName('btnBrowseDriversFolder') $State.Controls.btnBrowsePEDriversFolder = $window.FindName('btnBrowsePEDriversFolder') $State.Controls.txtAppName = $window.FindName('txtAppName') $State.Controls.txtAppCommandLine = $window.FindName('txtAppCommandLine') $State.Controls.txtAppArguments = $window.FindName('txtAppArguments') $State.Controls.txtAppSource = $window.FindName('txtAppSource') $State.Controls.btnAddApplication = $window.FindName('btnAddApplication') $State.Controls.btnSaveBYOApplications = $window.FindName('btnSaveBYOApplications') $State.Controls.btnLoadBYOApplications = $window.FindName('btnLoadBYOApplications') $State.Controls.btnClearBYOApplications = $window.FindName('btnClearBYOApplications') $State.Controls.btnCopyBYOApps = $window.FindName('btnCopyBYOApps') $State.Controls.lstApplications = $window.FindName('lstApplications') $State.Controls.btnMoveTop = $window.FindName('btnMoveTop') $State.Controls.btnMoveUp = $window.FindName('btnMoveUp') $State.Controls.btnMoveDown = $window.FindName('btnMoveDown') $State.Controls.btnMoveBottom = $window.FindName('btnMoveBottom') $State.Controls.txtStatus = $window.FindName('txtStatus') $State.Controls.pbOverallProgress = $window.FindName('progressBar') $State.Controls.txtOverallStatus = $window.FindName('txtStatus') $State.Controls.cmbVMSwitchName = $window.FindName('cmbVMSwitchName') $State.Controls.txtVMHostIPAddress = $window.FindName('txtVMHostIPAddress') $State.Controls.txtCustomVMSwitchName = $window.FindName('txtCustomVMSwitchName') $State.Controls.txtFFUDevPath = $window.FindName('txtFFUDevPath') $State.Controls.txtCustomFFUNameTemplate = $window.FindName('txtCustomFFUNameTemplate') $State.Controls.txtFFUCaptureLocation = $window.FindName('txtFFUCaptureLocation') $State.Controls.txtShareName = $window.FindName('txtShareName') $State.Controls.txtUsername = $window.FindName('txtUsername') $State.Controls.chkCompactOS = $window.FindName('chkCompactOS') $State.Controls.chkOptimize = $window.FindName('chkOptimize') $State.Controls.chkAllowVHDXCaching = $window.FindName('chkAllowVHDXCaching') $State.Controls.chkCreateCaptureMedia = $window.FindName('chkCreateCaptureMedia') $State.Controls.chkCreateDeploymentMedia = $window.FindName('chkCreateDeploymentMedia') $State.Controls.chkCopyAutopilot = $window.FindName('chkCopyAutopilot') $State.Controls.chkCopyUnattend = $window.FindName('chkCopyUnattend') $State.Controls.chkCopyPPKG = $window.FindName('chkCopyPPKG') $State.Controls.chkCleanupAppsISO = $window.FindName('chkCleanupAppsISO') $State.Controls.chkCleanupCaptureISO = $window.FindName('chkCleanupCaptureISO') $State.Controls.chkCleanupDeployISO = $window.FindName('chkCleanupDeployISO') $State.Controls.chkCleanupDrivers = $window.FindName('chkCleanupDrivers') $State.Controls.chkRemoveFFU = $window.FindName('chkRemoveFFU') $State.Controls.txtDiskSize = $window.FindName('txtDiskSize') $State.Controls.txtMemory = $window.FindName('txtMemory') $State.Controls.txtProcessors = $window.FindName('txtProcessors') $State.Controls.txtVMLocation = $window.FindName('txtVMLocation') $State.Controls.txtVMNamePrefix = $window.FindName('txtVMNamePrefix') $State.Controls.cmbLogicalSectorSize = $window.FindName('cmbLogicalSectorSize') $State.Controls.txtProductKey = $window.FindName('txtProductKey') $State.Controls.txtOfficePath = $window.FindName('txtOfficePath') $State.Controls.txtOfficeConfigXMLFilePath = $window.FindName('txtOfficeConfigXMLFilePath') $State.Controls.txtDriversFolder = $window.FindName('txtDriversFolder') $State.Controls.txtPEDriversFolder = $window.FindName('txtPEDriversFolder') $State.Controls.chkCopyPEDrivers = $window.FindName('chkCopyPEDrivers') $State.Controls.chkUpdateLatestCU = $window.FindName('chkUpdateLatestCU') $State.Controls.chkUpdateLatestNet = $window.FindName('chkUpdateLatestNet') $State.Controls.chkUpdateLatestDefender = $window.FindName('chkUpdateLatestDefender') $State.Controls.chkUpdateEdge = $window.FindName('chkUpdateEdge') $State.Controls.chkUpdateOneDrive = $window.FindName('chkUpdateOneDrive') $State.Controls.chkUpdateLatestMSRT = $window.FindName('chkUpdateLatestMSRT') $State.Controls.chkUpdatePreviewCU = $window.FindName('chkUpdatePreviewCU') $State.Controls.txtApplicationPath = $window.FindName('txtApplicationPath') $State.Controls.txtAppListJsonPath = $window.FindName('txtAppListJsonPath') $State.Controls.chkInstallDrivers = $window.FindName('chkInstallDrivers') $State.Controls.chkCopyDrivers = $window.FindName('chkCopyDrivers') $State.Controls.chkCompressDriversToWIM = $window.FindName('chkCompressDriversToWIM') $State.Controls.chkRemoveApps = $window.FindName('chkRemoveApps') $State.Controls.chkRemoveUpdates = $window.FindName('chkRemoveUpdates') $State.Controls.chkUpdateLatestMicrocode = $window.FindName('chkUpdateLatestMicrocode') $State.Controls.chkDefineAppsScriptVariables = $window.FindName('chkDefineAppsScriptVariables') $State.Controls.appsScriptVariablesPanel = $window.FindName('appsScriptVariablesPanel') $State.Controls.txtAppsScriptKey = $window.FindName('txtAppsScriptKey') $State.Controls.txtAppsScriptValue = $window.FindName('txtAppsScriptValue') $State.Controls.btnAddAppsScriptVariable = $window.FindName('btnAddAppsScriptVariable') $State.Controls.lstAppsScriptVariables = $window.FindName('lstAppsScriptVariables') $State.Controls.btnRemoveSelectedAppsScriptVariables = $window.FindName('btnRemoveSelectedAppsScriptVariables') $State.Controls.btnClearAppsScriptVariables = $window.FindName('btnClearAppsScriptVariables') $State.Controls.txtDriversJsonPath = $window.FindName('txtDriversJsonPath') $State.Controls.btnBrowseDriversJsonPath = $window.FindName('btnBrowseDriversJsonPath') $State.Controls.chkUpdateADK = $window.FindName('chkUpdateADK') } function Initialize-DynamicUIElements { param([PSCustomObject]$State) WriteLog "Initializing dynamic UI elements (Grids, Columns)..." # Driver Models ListView setup # Set ListViewItem style to stretch content horizontally so cell templates fill the cell $itemStyleDriverModels = New-Object System.Windows.Style([System.Windows.Controls.ListViewItem]) $itemStyleDriverModels.Setters.Add((New-Object System.Windows.Setter([System.Windows.Controls.ListViewItem]::HorizontalContentAlignmentProperty, [System.Windows.HorizontalAlignment]::Stretch))) $State.Controls.lstDriverModels.ItemContainerStyle = $itemStyleDriverModels $driverModelsGridView = New-Object System.Windows.Controls.GridView $State.Controls.lstDriverModels.View = $driverModelsGridView # Assign GridView to ListView first # Add the selectable column using the new function Add-SelectableGridViewColumn -ListView $State.Controls.lstDriverModels -HeaderCheckBoxScriptVariableName "chkSelectAllDriverModels" -ColumnWidth 70 # Add other sortable columns with left-aligned headers Add-SortableColumn -gridView $driverModelsGridView -header "Make" -binding "Make" -width 100 -headerHorizontalAlignment Left Add-SortableColumn -gridView $driverModelsGridView -header "Model" -binding "Model" -width 200 -headerHorizontalAlignment Left Add-SortableColumn -gridView $driverModelsGridView -header "Download Status" -binding "DownloadStatus" -width 150 -headerHorizontalAlignment Left $State.Controls.lstDriverModels.AddHandler( [System.Windows.Controls.GridViewColumnHeader]::ClickEvent, [System.Windows.RoutedEventHandler] { param($eventSource, $e) # $eventSource is the ListView control $header = $e.OriginalSource if ($header -is [System.Windows.Controls.GridViewColumnHeader] -and $header.Tag) { # Retrieve the main UI state object from the window's Tag property $listViewControl = $eventSource $window = [System.Windows.Window]::GetWindow($listViewControl) $uiStateFromWindowTag = $window.Tag Invoke-ListViewSort -listView $eventSource -property $header.Tag -State $uiStateFromWindowTag } } ) # Winget Search ListView setup $wingetGridView = New-Object System.Windows.Controls.GridView $State.Controls.lstWingetResults.View = $wingetGridView # Assign GridView to ListView first # Set ListViewItem style to stretch content horizontally so cell templates fill the cell $itemStyleWingetResults = New-Object System.Windows.Style([System.Windows.Controls.ListViewItem]) $itemStyleWingetResults.Setters.Add((New-Object System.Windows.Setter([System.Windows.Controls.ListViewItem]::HorizontalContentAlignmentProperty, [System.Windows.HorizontalAlignment]::Stretch))) $State.Controls.lstWingetResults.ItemContainerStyle = $itemStyleWingetResults # Add the selectable column using the new function Add-SelectableGridViewColumn -ListView $State.Controls.lstWingetResults -HeaderCheckBoxScriptVariableName "chkSelectAllWingetResults" -ColumnWidth 60 # Add other sortable columns with left-aligned headers Add-SortableColumn -gridView $wingetGridView -header "Name" -binding "Name" -width 200 -headerHorizontalAlignment Left Add-SortableColumn -gridView $wingetGridView -header "Id" -binding "Id" -width 200 -headerHorizontalAlignment Left Add-SortableColumn -gridView $wingetGridView -header "Version" -binding "Version" -width 100 -headerHorizontalAlignment Left Add-SortableColumn -gridView $wingetGridView -header "Source" -binding "Source" -width 100 -headerHorizontalAlignment Left Add-SortableColumn -gridView $wingetGridView -header "Download Status" -binding "DownloadStatus" -width 150 -headerHorizontalAlignment Left $State.Controls.lstWingetResults.AddHandler( [System.Windows.Controls.GridViewColumnHeader]::ClickEvent, [System.Windows.RoutedEventHandler] { param($eventSource, $e) # $eventSource is the ListView control $header = $e.OriginalSource if ($header -is [System.Windows.Controls.GridViewColumnHeader] -and $header.Tag) { # Retrieve the main UI state object from the window's Tag property $listViewControl = $eventSource $window = [System.Windows.Window]::GetWindow($listViewControl) $uiStateFromWindowTag = $window.Tag Invoke-ListViewSort -listView $eventSource -property $header.Tag -State $uiStateFromWindowTag } } ) # Apps Script Variables ListView setup # Bind ItemsSource to the data list $State.Controls.lstAppsScriptVariables.ItemsSource = $State.Data.appsScriptVariablesDataList.ToArray() # Set ListViewItem style to stretch content horizontally so cell templates fill the cell $itemStyleAppsScriptVars = New-Object System.Windows.Style([System.Windows.Controls.ListViewItem]) $itemStyleAppsScriptVars.Setters.Add((New-Object System.Windows.Setter([System.Windows.Controls.ListViewItem]::HorizontalContentAlignmentProperty, [System.Windows.HorizontalAlignment]::Stretch))) $State.Controls.lstAppsScriptVariables.ItemContainerStyle = $itemStyleAppsScriptVars # The GridView for lstAppsScriptVariables is defined in XAML. We need to get it and add the column. if ($State.Controls.lstAppsScriptVariables.View -is [System.Windows.Controls.GridView]) { Add-SelectableGridViewColumn -ListView $State.Controls.lstAppsScriptVariables -HeaderCheckBoxScriptVariableName "chkSelectAllAppsScriptVariables" -ColumnWidth 60 # Make Key and Value columns sortable $appsScriptVarsGridView = $State.Controls.lstAppsScriptVariables.View # Key Column (should be at index 1 after selectable column is inserted at 0) if ($appsScriptVarsGridView.Columns.Count -gt 1) { $keyColumn = $appsScriptVarsGridView.Columns[1] $keyHeader = New-Object System.Windows.Controls.GridViewColumnHeader $keyHeader.Content = "Key" $keyHeader.Tag = "Key" # Property to sort by $keyHeader.HorizontalContentAlignment = [System.Windows.HorizontalAlignment]::Left $keyColumn.Header = $keyHeader } # Value Column (should be at index 2) if ($appsScriptVarsGridView.Columns.Count -gt 2) { $valueColumn = $appsScriptVarsGridView.Columns[2] $valueHeader = New-Object System.Windows.Controls.GridViewColumnHeader $valueHeader.Content = "Value" $valueHeader.Tag = "Value" # Property to sort by $valueHeader.HorizontalContentAlignment = [System.Windows.HorizontalAlignment]::Left $valueColumn.Header = $valueHeader } # Add Click event handler for sorting $State.Controls.lstAppsScriptVariables.AddHandler( [System.Windows.Controls.GridViewColumnHeader]::ClickEvent, [System.Windows.RoutedEventHandler] { param($eventSource, $e) # $eventSource is the ListView control $header = $e.OriginalSource if ($header -is [System.Windows.Controls.GridViewColumnHeader] -and $header.Tag) { # Retrieve the main UI state object from the window's Tag property $listViewControl = $eventSource $window = [System.Windows.Window]::GetWindow($listViewControl) $uiStateFromWindowTag = $window.Tag Invoke-ListViewSort -listView $eventSource -property $header.Tag -State $uiStateFromWindowTag } } ) } else { WriteLog "Warning: lstAppsScriptVariables.View is not a GridView. Selectable column not added, and sorting cannot be enabled." } # Build dynamic multi-column checkboxes for optional features if ($State.Controls.featuresPanel -and $State.Defaults.windowsSettingsDefaults) { BuildFeaturesGrid -parent $State.Controls.featuresPanel -allowedFeatures $State.Defaults.windowsSettingsDefaults.AllowedFeatures -State $State } else { WriteLog "Initialize-DynamicUIElements: Could not build features grid. Panel or defaults missing." } } Export-ModuleMember -Function Initialize-UIControls, Initialize-DynamicUIElements