mirror of
https://github.com/rbalsleyMSFT/FFU.git
synced 2026-06-14 10:19:36 -06:00
61ec7509ad
Centralizes the `btnGetModels` click event handler from the main UI script into the `FFUUI.Core` module to improve code organization and separation of concerns. The handler is updated to use the local state object instead of a global script variable. The logic for updating the model list is also improved to preserve the collection's object reference, ensuring data binding stability.
583 lines
38 KiB
PowerShell
583 lines
38 KiB
PowerShell
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-UIDefaults {
|
|
param([PSCustomObject]$State)
|
|
WriteLog "Initializing UI defaults..."
|
|
|
|
# Get default values from helper functions
|
|
$State.Defaults.windowsSettingsDefaults = Get-WindowsSettingsDefaults
|
|
$State.Defaults.generalDefaults = Get-GeneralDefaults -FFUDevelopmentPath $State.FFUDevelopmentPath
|
|
|
|
# Build tab defaults from General Defaults
|
|
$State.Controls.txtFFUDevPath.Text = $State.FFUDevelopmentPath
|
|
$State.Controls.txtCustomFFUNameTemplate.Text = $State.Defaults.generalDefaults.CustomFFUNameTemplate
|
|
$State.Controls.txtFFUCaptureLocation.Text = $State.Defaults.generalDefaults.FFUCaptureLocation
|
|
$State.Controls.txtShareName.Text = $State.Defaults.generalDefaults.ShareName
|
|
$State.Controls.txtUsername.Text = $State.Defaults.generalDefaults.Username
|
|
$State.Controls.chkBuildUSBDriveEnable.IsChecked = $State.Defaults.generalDefaults.BuildUSBDriveEnable
|
|
$State.Controls.chkCompactOS.IsChecked = $State.Defaults.generalDefaults.CompactOS
|
|
$State.Controls.chkUpdateADK.IsChecked = $State.Defaults.generalDefaults.UpdateADK
|
|
$State.Controls.chkOptimize.IsChecked = $State.Defaults.generalDefaults.Optimize
|
|
$State.Controls.chkAllowVHDXCaching.IsChecked = $State.Defaults.generalDefaults.AllowVHDXCaching
|
|
$State.Controls.chkCreateCaptureMedia.IsChecked = $State.Defaults.generalDefaults.CreateCaptureMedia
|
|
$State.Controls.chkCreateDeploymentMedia.IsChecked = $State.Defaults.generalDefaults.CreateDeploymentMedia
|
|
$State.Controls.chkAllowExternalHardDiskMedia.IsChecked = $State.Defaults.generalDefaults.AllowExternalHardDiskMedia
|
|
$State.Controls.chkPromptExternalHardDiskMedia.IsChecked = $State.Defaults.generalDefaults.PromptExternalHardDiskMedia
|
|
$State.Controls.chkSelectSpecificUSBDrives.IsChecked = $State.Defaults.generalDefaults.SelectSpecificUSBDrives
|
|
$State.Controls.chkCopyAutopilot.IsChecked = $State.Defaults.generalDefaults.CopyAutopilot
|
|
$State.Controls.chkCopyUnattend.IsChecked = $State.Defaults.generalDefaults.CopyUnattend
|
|
$State.Controls.chkCopyPPKG.IsChecked = $State.Defaults.generalDefaults.CopyPPKG
|
|
$State.Controls.chkCleanupAppsISO.IsChecked = $State.Defaults.generalDefaults.CleanupAppsISO
|
|
$State.Controls.chkCleanupCaptureISO.IsChecked = $State.Defaults.generalDefaults.CleanupCaptureISO
|
|
$State.Controls.chkCleanupDeployISO.IsChecked = $State.Defaults.generalDefaults.CleanupDeployISO
|
|
$State.Controls.chkCleanupDrivers.IsChecked = $State.Defaults.generalDefaults.CleanupDrivers
|
|
$State.Controls.chkRemoveFFU.IsChecked = $State.Defaults.generalDefaults.RemoveFFU
|
|
$State.Controls.chkRemoveApps.IsChecked = $State.Defaults.generalDefaults.RemoveApps
|
|
$State.Controls.chkRemoveUpdates.IsChecked = $State.Defaults.generalDefaults.RemoveUpdates
|
|
|
|
# Hyper-V Settings defaults from General Defaults
|
|
$State.Controls.txtDiskSize.Text = $State.Defaults.generalDefaults.DiskSizeGB
|
|
$State.Controls.txtMemory.Text = $State.Defaults.generalDefaults.MemoryGB
|
|
$State.Controls.txtProcessors.Text = $State.Defaults.generalDefaults.Processors
|
|
$State.Controls.txtVMLocation.Text = $State.Defaults.generalDefaults.VMLocation
|
|
$State.Controls.txtVMNamePrefix.Text = $State.Defaults.generalDefaults.VMNamePrefix
|
|
$State.Controls.cmbLogicalSectorSize.SelectedItem = ($State.Controls.cmbLogicalSectorSize.Items | Where-Object { $_.Content -eq $State.Defaults.generalDefaults.LogicalSectorSize.ToString() })
|
|
|
|
# Populate Windows Release, Version, and SKU comboboxes
|
|
Get-WindowsSettingsCombos -isoPath $State.Defaults.windowsSettingsDefaults.DefaultISOPath -State $State
|
|
|
|
# Windows Settings tab defaults
|
|
$State.Controls.cmbWindowsArch.ItemsSource = $State.Defaults.windowsSettingsDefaults.AllowedArchitectures
|
|
$State.Controls.cmbWindowsArch.SelectedItem = $State.Defaults.windowsSettingsDefaults.DefaultWindowsArch
|
|
$State.Controls.cmbWindowsLang.ItemsSource = $State.Defaults.windowsSettingsDefaults.AllowedLanguages
|
|
$State.Controls.cmbWindowsLang.SelectedItem = $State.Defaults.windowsSettingsDefaults.DefaultWindowsLang
|
|
$State.Controls.cmbWindowsSKU.SelectedItem = $State.Defaults.windowsSettingsDefaults.DefaultWindowsSKU
|
|
$State.Controls.cmbMediaType.ItemsSource = $State.Defaults.windowsSettingsDefaults.AllowedMediaTypes
|
|
$State.Controls.cmbMediaType.SelectedItem = $State.Defaults.windowsSettingsDefaults.DefaultMediaType
|
|
$State.Controls.txtOptionalFeatures.Text = $State.Defaults.windowsSettingsDefaults.DefaultOptionalFeatures
|
|
$State.Controls.txtProductKey.Text = $State.Defaults.windowsSettingsDefaults.DefaultProductKey
|
|
|
|
# Updates tab defaults from General Defaults
|
|
$State.Controls.chkUpdateLatestCU.IsChecked = $State.Defaults.generalDefaults.UpdateLatestCU
|
|
$State.Controls.chkUpdateLatestNet.IsChecked = $State.Defaults.generalDefaults.UpdateLatestNet
|
|
$State.Controls.chkUpdateLatestDefender.IsChecked = $State.Defaults.generalDefaults.UpdateLatestDefender
|
|
$State.Controls.chkUpdateEdge.IsChecked = $State.Defaults.generalDefaults.UpdateEdge
|
|
$State.Controls.chkUpdateOneDrive.IsChecked = $State.Defaults.generalDefaults.UpdateOneDrive
|
|
$State.Controls.chkUpdateLatestMSRT.IsChecked = $State.Defaults.generalDefaults.UpdateLatestMSRT
|
|
$State.Controls.chkUpdateLatestMicrocode.IsChecked = $State.Defaults.generalDefaults.UpdateLatestMicrocode
|
|
$State.Controls.chkUpdatePreviewCU.IsChecked = $State.Defaults.generalDefaults.UpdatePreviewCU
|
|
|
|
# Applications tab defaults from General Defaults
|
|
$State.Controls.chkInstallApps.IsChecked = $State.Defaults.generalDefaults.InstallApps
|
|
$State.Controls.txtApplicationPath.Text = $State.Defaults.generalDefaults.ApplicationPath
|
|
$State.Controls.txtAppListJsonPath.Text = $State.Defaults.generalDefaults.AppListJsonPath
|
|
$State.Controls.chkInstallWingetApps.IsChecked = $State.Defaults.generalDefaults.InstallWingetApps
|
|
$State.Controls.chkBringYourOwnApps.IsChecked = $State.Defaults.generalDefaults.BringYourOwnApps
|
|
|
|
# M365 Apps/Office tab defaults from General Defaults
|
|
$State.Controls.chkInstallOffice.IsChecked = $State.Defaults.generalDefaults.InstallOffice
|
|
$State.Controls.txtOfficePath.Text = $State.Defaults.generalDefaults.OfficePath
|
|
$State.Controls.chkCopyOfficeConfigXML.IsChecked = $State.Defaults.generalDefaults.CopyOfficeConfigXML
|
|
$State.Controls.txtOfficeConfigXMLFilePath.Text = $State.Defaults.generalDefaults.OfficeConfigXMLFilePath
|
|
|
|
# Drivers tab defaults from General Defaults
|
|
$State.Controls.txtDriversFolder.Text = $State.Defaults.generalDefaults.DriversFolder
|
|
$State.Controls.txtPEDriversFolder.Text = $State.Defaults.generalDefaults.PEDriversFolder
|
|
$State.Controls.txtDriversJsonPath.Text = $State.Defaults.generalDefaults.DriversJsonPath
|
|
$State.Controls.chkDownloadDrivers.IsChecked = $State.Defaults.generalDefaults.DownloadDrivers
|
|
$State.Controls.chkInstallDrivers.IsChecked = $State.Defaults.generalDefaults.InstallDrivers
|
|
$State.Controls.chkCopyDrivers.IsChecked = $State.Defaults.generalDefaults.CopyDrivers
|
|
$State.Controls.chkCopyPEDrivers.IsChecked = $State.Defaults.generalDefaults.CopyPEDrivers
|
|
}
|
|
|
|
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."
|
|
}
|
|
}
|
|
|
|
function Initialize-VMSwitchData {
|
|
param([PSCustomObject]$State)
|
|
|
|
WriteLog "Initializing VM Switch data..."
|
|
|
|
# Hyper-V Settings: Populate VM Switch ComboBox
|
|
$vmSwitchData = Get-VMSwitchData
|
|
$State.Data.vmSwitchMap = $vmSwitchData.SwitchMap
|
|
$State.Controls.cmbVMSwitchName.Items.Clear()
|
|
foreach ($switchName in $vmSwitchData.SwitchNames) {
|
|
$State.Controls.cmbVMSwitchName.Items.Add($switchName) | Out-Null
|
|
}
|
|
$State.Controls.cmbVMSwitchName.Items.Add('Other') | Out-Null
|
|
if ($State.Controls.cmbVMSwitchName.Items.Count -gt 1) {
|
|
$State.Controls.cmbVMSwitchName.SelectedIndex = 0
|
|
$firstSwitch = $State.Controls.cmbVMSwitchName.SelectedItem
|
|
if ($State.Data.vmSwitchMap.ContainsKey($firstSwitch)) {
|
|
$State.Controls.txtVMHostIPAddress.Text = $State.Data.vmSwitchMap[$firstSwitch]
|
|
}
|
|
else {
|
|
$State.Controls.txtVMHostIPAddress.Text = $State.Defaults.generalDefaults.VMHostIPAddress # Use default if IP not found
|
|
}
|
|
$State.Controls.txtCustomVMSwitchName.Visibility = 'Collapsed'
|
|
}
|
|
else {
|
|
$State.Controls.cmbVMSwitchName.SelectedItem = 'Other'
|
|
$State.Controls.txtCustomVMSwitchName.Visibility = 'Visible'
|
|
$State.Controls.txtVMHostIPAddress.Text = $State.Defaults.generalDefaults.VMHostIPAddress # Use default
|
|
}
|
|
}
|
|
|
|
function Register-EventHandlers {
|
|
param([PSCustomObject]$State)
|
|
WriteLog "Registering UI event handlers..."
|
|
|
|
# Hyper-V tab event handlers
|
|
$State.Controls.cmbVMSwitchName.Add_SelectionChanged({
|
|
param($eventSource, $selectionChangedEventArgs)
|
|
# The state object is available via the parent window's Tag property
|
|
$window = [System.Windows.Window]::GetWindow($eventSource)
|
|
$localState = $window.Tag
|
|
|
|
$selectedItem = $eventSource.SelectedItem
|
|
if ($selectedItem -eq 'Other') {
|
|
$localState.Controls.txtCustomVMSwitchName.Visibility = 'Visible'
|
|
$localState.Controls.txtVMHostIPAddress.Text = '' # Clear IP for custom
|
|
}
|
|
else {
|
|
$localState.Controls.txtCustomVMSwitchName.Visibility = 'Collapsed'
|
|
if ($localState.Data.vmSwitchMap.ContainsKey($selectedItem)) {
|
|
$localState.Controls.txtVMHostIPAddress.Text = $localState.Data.vmSwitchMap[$selectedItem]
|
|
}
|
|
else {
|
|
$localState.Controls.txtVMHostIPAddress.Text = '' # Clear IP if not found in map
|
|
}
|
|
}
|
|
})
|
|
|
|
# Windows Settings tab Event Handlers
|
|
$State.Controls.txtISOPath.Add_TextChanged({
|
|
param($eventSource, $textChangedEventArgs)
|
|
$window = [System.Windows.Window]::GetWindow($eventSource)
|
|
$localState = $window.Tag
|
|
Get-WindowsSettingsCombos -isoPath $localState.Controls.txtISOPath.Text -State $localState
|
|
})
|
|
|
|
$State.Controls.cmbWindowsRelease.Add_SelectionChanged({
|
|
param($eventSource, $selectionChangedEventArgs)
|
|
$window = [System.Windows.Window]::GetWindow($eventSource)
|
|
$localState = $window.Tag
|
|
$selectedReleaseValue = 11 # Default if null
|
|
if ($null -ne $localState.Controls.cmbWindowsRelease.SelectedItem) {
|
|
$selectedReleaseValue = $localState.Controls.cmbWindowsRelease.SelectedItem.Value
|
|
}
|
|
# Only need to update the Version combo when Release changes
|
|
Update-WindowsVersionCombo -selectedRelease $selectedReleaseValue -isoPath $localState.Controls.txtISOPath.Text -State $localState
|
|
# Also update the SKU combo (now derives values internally)
|
|
Update-WindowsSkuCombo -State $localState
|
|
})
|
|
|
|
$State.Controls.btnBrowseISO.Add_Click({
|
|
param($eventSource, $routedEventArgs)
|
|
$window = [System.Windows.Window]::GetWindow($eventSource)
|
|
$localState = $window.Tag
|
|
$ofd = New-Object System.Windows.Forms.OpenFileDialog
|
|
$ofd.Filter = "ISO files (*.iso)|*.iso"
|
|
$ofd.Title = "Select Windows ISO File"
|
|
if ($ofd.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) { $localState.Controls.txtISOPath.Text = $ofd.FileName }
|
|
})
|
|
|
|
# Drivers Tab Event Handlers
|
|
$State.Controls.chkDownloadDrivers.Add_Checked({
|
|
param($eventSource, $routedEventArgs)
|
|
$window = [System.Windows.Window]::GetWindow($eventSource)
|
|
$localState = $window.Tag
|
|
$localState.Controls.cmbMake.Visibility = 'Visible'
|
|
$localState.Controls.btnGetModels.Visibility = 'Visible'
|
|
$localState.Controls.spMakeSection.Visibility = 'Visible'
|
|
$localState.Controls.spModelFilterSection.Visibility = 'Visible'
|
|
$localState.Controls.lstDriverModels.Visibility = 'Visible'
|
|
$localState.Controls.spDriverActionButtons.Visibility = 'Visible'
|
|
})
|
|
$State.Controls.chkDownloadDrivers.Add_Unchecked({
|
|
param($eventSource, $routedEventArgs)
|
|
$window = [System.Windows.Window]::GetWindow($eventSource)
|
|
$localState = $window.Tag
|
|
$localState.Controls.cmbMake.Visibility = 'Collapsed'
|
|
$localState.Controls.btnGetModels.Visibility = 'Collapsed'
|
|
$localState.Controls.spMakeSection.Visibility = 'Collapsed'
|
|
$localState.Controls.spModelFilterSection.Visibility = 'Collapsed'
|
|
$localState.Controls.lstDriverModels.Visibility = 'Collapsed'
|
|
$localState.Controls.spDriverActionButtons.Visibility = 'Collapsed'
|
|
$localState.Controls.lstDriverModels.ItemsSource = $null
|
|
$localState.Data.allDriverModels.Clear()
|
|
$localState.Controls.txtModelFilter.Text = ""
|
|
})
|
|
|
|
$State.Controls.btnGetModels.Add_Click({
|
|
param($eventSource, $routedEventArgs)
|
|
$window = [System.Windows.Window]::GetWindow($eventSource)
|
|
$localState = $window.Tag
|
|
|
|
$selectedMake = $localState.Controls.cmbMake.SelectedItem
|
|
$localState.Controls.txtStatus.Text = "Getting models for $selectedMake..."
|
|
$window.Cursor = [System.Windows.Input.Cursors]::Wait
|
|
$eventSource.IsEnabled = $false
|
|
try {
|
|
# Get previously selected models from the master list ($localState.Data.allDriverModels)
|
|
$previouslySelectedModels = @($localState.Data.allDriverModels | Where-Object { $_.IsSelected })
|
|
|
|
# Get newly fetched models for the current make
|
|
$newlyFetchedStandardizedModels = Get-ModelsForMake -SelectedMake $selectedMake -State $localState
|
|
|
|
$combinedModelsList = [System.Collections.Generic.List[PSCustomObject]]::new()
|
|
$modelIdentifiersInCombinedList = [System.Collections.Generic.HashSet[string]]::new([System.StringComparer]::OrdinalIgnoreCase)
|
|
|
|
# Add previously selected models first
|
|
foreach ($item in $previouslySelectedModels) {
|
|
$combinedModelsList.Add($item)
|
|
$modelIdentifiersInCombinedList.Add("$($item.Make)::$($item.Model)") | Out-Null
|
|
}
|
|
|
|
# Add newly fetched models if they are not already in the list
|
|
$addedNewCount = 0
|
|
foreach ($item in $newlyFetchedStandardizedModels) {
|
|
if (-not $modelIdentifiersInCombinedList.Contains("$($item.Make)::$($item.Model)")) {
|
|
$combinedModelsList.Add($item)
|
|
$modelIdentifiersInCombinedList.Add("$($item.Make)::$($item.Model)") | Out-Null
|
|
$addedNewCount++
|
|
}
|
|
}
|
|
|
|
# Sort the combined list and update the master list while preserving its List<> type
|
|
$sortedModels = $combinedModelsList | Sort-Object @{Expression = { $_.IsSelected }; Descending = $true }, Make, Model
|
|
$localState.Data.allDriverModels.Clear()
|
|
$sortedModels.ForEach({ $localState.Data.allDriverModels.Add($_) })
|
|
|
|
# Update the UI
|
|
$localState.Controls.lstDriverModels.ItemsSource = $localState.Data.allDriverModels
|
|
$localState.Controls.txtModelFilter.Text = ""
|
|
|
|
if ($localState.Data.allDriverModels.Count -gt 0) {
|
|
$localState.Controls.spModelFilterSection.Visibility = 'Visible'
|
|
$localState.Controls.lstDriverModels.Visibility = 'Visible'
|
|
$localState.Controls.spDriverActionButtons.Visibility = 'Visible'
|
|
$statusText = "Displaying $($localState.Data.allDriverModels.Count) models."
|
|
if ($newlyFetchedStandardizedModels.Count -gt 0 -and $addedNewCount -eq 0 -and $previouslySelectedModels.Count -gt 0) {
|
|
$statusText = "Fetched $($newlyFetchedStandardizedModels.Count) models for $selectedMake; all were already in the selected list. Displaying $($localState.Data.allDriverModels.Count) total selected models."
|
|
}
|
|
elseif ($addedNewCount -gt 0) {
|
|
$statusText = "Added $addedNewCount new models for $selectedMake. Displaying $($localState.Data.allDriverModels.Count) total models."
|
|
}
|
|
elseif ($newlyFetchedStandardizedModels.Count -eq 0 -and $selectedMake -eq 'Lenovo' ) {
|
|
$statusText = if ($previouslySelectedModels.Count -gt 0) { "No new models found for $selectedMake. Displaying $($previouslySelectedModels.Count) previously selected models." } else { "No models found for $selectedMake." }
|
|
}
|
|
elseif ($newlyFetchedStandardizedModels.Count -eq 0) {
|
|
$statusText = "No new models found for $selectedMake. Displaying $($localState.Data.allDriverModels.Count) previously selected models."
|
|
}
|
|
$localState.Controls.txtStatus.Text = $statusText
|
|
}
|
|
else {
|
|
$localState.Controls.spModelFilterSection.Visibility = 'Collapsed'
|
|
$localState.Controls.lstDriverModels.Visibility = 'Collapsed'
|
|
$localState.Controls.spDriverActionButtons.Visibility = 'Collapsed'
|
|
$localState.Controls.txtStatus.Text = "No models to display for $selectedMake."
|
|
}
|
|
}
|
|
catch {
|
|
$localState.Controls.txtStatus.Text = "Error getting models: $($_.Exception.Message)"
|
|
[System.Windows.MessageBox]::Show("Error getting models: $($_.Exception.Message)", "Error", "OK", "Error")
|
|
if ($null -eq $localState.Data.allDriverModels -or $localState.Data.allDriverModels.Count -eq 0) {
|
|
$localState.Controls.spModelFilterSection.Visibility = 'Collapsed'
|
|
$localState.Controls.lstDriverModels.Visibility = 'Collapsed'
|
|
$localState.Controls.spDriverActionButtons.Visibility = 'Collapsed'
|
|
$localState.Controls.lstDriverModels.ItemsSource = $null
|
|
$localState.Controls.txtModelFilter.Text = ""
|
|
}
|
|
}
|
|
finally {
|
|
$window.Cursor = $null
|
|
$eventSource.IsEnabled = $true
|
|
}
|
|
})
|
|
}
|
|
|
|
Export-ModuleMember -Function *
|