mirror of
https://github.com/Raphire/Win11Debloat.git
synced 2026-06-10 18:46:28 +00:00
* Remove RemoveCommApps and RemoveW11Outlook presets. These are largely redundant. Use -RemoveApps parameter instead * Add additional options to change the `All Apps` view in the start menu (Hide, Grid, Category, List) * Add clean start menu backup validation to start menu restore function * Resolve nested quoting bug in Run.bat when path has spaces, see #583 * Fix desync issue when toggling "Only Show Installed" checkbox too fast * Fix: add missing keys in Sysprep/Undo regfiles for Disabling Recall and Windows Suggested content * Fix 'Disable Animations' Sysprep settings not being set for new users * Update README.md * Update CONTRIBUTING.md
512 lines
22 KiB
PowerShell
512 lines
22 KiB
PowerShell
# MainWindow-TweaksBuilder.ps1
|
|
# Dynamic tweaks UI construction from Features.json, tweak state management, selection clear, and search/highlight.
|
|
|
|
function Build-DynamicTweaks {
|
|
param(
|
|
[System.Windows.Window]$Window,
|
|
[int]$WinVersion
|
|
)
|
|
|
|
$featuresJson = LoadJsonFile -filePath $script:FeaturesFilePath -expectedVersion "1.0"
|
|
|
|
if (-not $featuresJson) {
|
|
throw "Unable to load Features.json file. The GUI cannot continue without feature definitions."
|
|
}
|
|
|
|
# Column containers
|
|
$col0 = $Window.FindName('Column0Panel')
|
|
$col1 = $Window.FindName('Column1Panel')
|
|
$col2 = $Window.FindName('Column2Panel')
|
|
$columns = @($col0, $col1, $col2) | Where-Object { $_ -ne $null }
|
|
|
|
# Clear all columns for fully dynamic panel creation
|
|
foreach ($col in $columns) {
|
|
if ($col) { $col.Children.Clear() }
|
|
}
|
|
|
|
$script:UiControlMappings = @{}
|
|
$script:CategoryCardMap = @{}
|
|
$script:TweaksCompactMode = $null
|
|
$script:TweaksCardsMovedFromCol2 = @()
|
|
|
|
function CreateLabeledCombo($parent, $labelText, $comboName, $items) {
|
|
# If only 2 items (No Change + one option), use a checkbox instead
|
|
if ($items.Count -eq 2) {
|
|
$checkbox = New-Object System.Windows.Controls.CheckBox
|
|
$checkbox.Content = $labelText
|
|
$checkbox.Name = $comboName
|
|
$checkbox.SetValue([System.Windows.Automation.AutomationProperties]::NameProperty, $labelText)
|
|
$checkbox.IsChecked = $false
|
|
$checkbox.Style = $Window.Resources["FeatureCheckboxStyle"]
|
|
$parent.Children.Add($checkbox) | Out-Null
|
|
|
|
# Register the checkbox with the window's name scope
|
|
try {
|
|
[System.Windows.NameScope]::SetNameScope($checkbox, [System.Windows.NameScope]::GetNameScope($Window))
|
|
$Window.RegisterName($comboName, $checkbox)
|
|
}
|
|
catch {
|
|
# Name might already be registered, ignore
|
|
}
|
|
|
|
return $checkbox
|
|
}
|
|
|
|
# Otherwise use a combobox for multiple options
|
|
# Wrap label in a Border for search highlighting
|
|
$lblBorder = New-Object System.Windows.Controls.Border
|
|
$lblBorder.Style = $Window.Resources['LabelBorderStyle']
|
|
$lblBorderName = "$comboName`_LabelBorder"
|
|
$lblBorder.Name = $lblBorderName
|
|
|
|
$lbl = New-Object System.Windows.Controls.TextBlock
|
|
$lbl.Text = $labelText
|
|
$lbl.Style = $Window.Resources['LabelStyle']
|
|
$labelName = "$comboName`_Label"
|
|
$lbl.Name = $labelName
|
|
|
|
$lblBorder.Child = $lbl
|
|
$parent.Children.Add($lblBorder) | Out-Null
|
|
|
|
# Register the label border with the window's name scope
|
|
try {
|
|
[System.Windows.NameScope]::SetNameScope($lblBorder, [System.Windows.NameScope]::GetNameScope($Window))
|
|
$Window.RegisterName($lblBorderName, $lblBorder)
|
|
}
|
|
catch {
|
|
# Name might already be registered, ignore
|
|
}
|
|
|
|
$combo = New-Object System.Windows.Controls.ComboBox
|
|
$combo.Name = $comboName
|
|
$combo.SetValue([System.Windows.Automation.AutomationProperties]::NameProperty, $labelText)
|
|
foreach ($item in $items) { $comboItem = New-Object System.Windows.Controls.ComboBoxItem; $comboItem.Content = $item; $combo.Items.Add($comboItem) | Out-Null }
|
|
$combo.SelectedIndex = 0
|
|
$parent.Children.Add($combo) | Out-Null
|
|
|
|
# Register the combo box with the window's name scope
|
|
try {
|
|
[System.Windows.NameScope]::SetNameScope($combo, [System.Windows.NameScope]::GetNameScope($Window))
|
|
$Window.RegisterName($comboName, $combo)
|
|
}
|
|
catch {
|
|
# Name might already be registered, ignore
|
|
}
|
|
|
|
return $combo
|
|
}
|
|
|
|
function GetWikiUrlForCategory($category) {
|
|
if (-not $category) { return 'https://github.com/Raphire/Win11Debloat/wiki/Features' }
|
|
|
|
$slug = $category.ToLowerInvariant()
|
|
$slug = $slug -replace '&', ''
|
|
$slug = $slug -replace '[^a-z0-9\s-]', ''
|
|
$slug = $slug -replace '\s', '-'
|
|
|
|
return "https://github.com/Raphire/Win11Debloat/wiki/Features#$slug"
|
|
}
|
|
|
|
function GetOrCreateCategoryCard($categoryObj) {
|
|
$categoryName = $categoryObj.Name
|
|
$categoryIcon = $categoryObj.Icon
|
|
|
|
if ($script:CategoryCardMap.ContainsKey($categoryName)) { return $script:CategoryCardMap[$categoryName] }
|
|
|
|
# Create a new card Border + StackPanel and add to shortest column
|
|
$target = $columns | Sort-Object @{Expression = { $_.Children.Count }; Ascending = $true }, @{Expression = { $columns.IndexOf($_) }; Ascending = $true } | Select-Object -First 1
|
|
|
|
$border = New-Object System.Windows.Controls.Border
|
|
$border.Style = $Window.Resources['CategoryCardBorderStyle']
|
|
$border.Tag = 'DynamicCategory'
|
|
|
|
$panel = New-Object System.Windows.Controls.StackPanel
|
|
$safe = ($categoryName -replace '[^a-zA-Z0-9_]', '_')
|
|
$panel.Name = "Category_{0}_Panel" -f $safe
|
|
|
|
$headerRow = New-Object System.Windows.Controls.StackPanel
|
|
$headerRow.Orientation = 'Horizontal'
|
|
|
|
# Add category icon
|
|
$icon = New-Object System.Windows.Controls.TextBlock
|
|
# Convert HTML entity to character (e.g.,  -> actual character)
|
|
if ($categoryIcon -match '&#x([0-9A-Fa-f]+);') {
|
|
$hexValue = [Convert]::ToInt32($matches[1], 16)
|
|
$icon.Text = [char]$hexValue
|
|
}
|
|
$icon.Style = $Window.Resources['CategoryHeaderIcon']
|
|
$headerRow.Children.Add($icon) | Out-Null
|
|
|
|
$header = New-Object System.Windows.Controls.TextBlock
|
|
$header.Text = $categoryName
|
|
$header.Style = $Window.Resources['CategoryHeaderTextBlock']
|
|
$headerRow.Children.Add($header) | Out-Null
|
|
|
|
$helpIcon = New-Object System.Windows.Controls.TextBlock
|
|
$helpIcon.Text = '(?)'
|
|
$helpIcon.Style = $Window.Resources['CategoryHelpLinkTextStyle']
|
|
|
|
$helpBtn = New-Object System.Windows.Controls.Button
|
|
$helpBtn.Content = $helpIcon
|
|
$helpBtn.ToolTip = "Open wiki for more info on '$categoryName' tweaks"
|
|
$helpBtn.Tag = (GetWikiUrlForCategory -category $categoryName)
|
|
$helpBtn.Style = $Window.Resources['CategoryHelpLinkButtonStyle']
|
|
$helpBtn.Add_Click({
|
|
param($button, $e)
|
|
if ($button.Tag) { Start-Process $button.Tag }
|
|
})
|
|
$headerRow.Children.Add($helpBtn) | Out-Null
|
|
|
|
$panel.Children.Add($headerRow) | Out-Null
|
|
|
|
$border.Child = $panel
|
|
$target.Children.Add($border) | Out-Null
|
|
|
|
$script:CategoryCardMap[$categoryName] = $panel
|
|
return $panel
|
|
}
|
|
|
|
# Determine categories present (from lists and features)
|
|
$categoriesPresent = @{}
|
|
if ($featuresJson.UiGroups) {
|
|
foreach ($g in $featuresJson.UiGroups) { if ($g.Category) { $categoriesPresent[$g.Category] = $true } }
|
|
}
|
|
foreach ($f in $featuresJson.Features) { if ($f.Category) { $categoriesPresent[$f.Category] = $true } }
|
|
|
|
# Create cards in the order defined in Features.json Categories (if present)
|
|
$orderedCategories = @()
|
|
if ($featuresJson.Categories) {
|
|
foreach ($c in $featuresJson.Categories) {
|
|
$categoryName = if ($c -is [string]) { $c } else { $c.Name }
|
|
if ($categoriesPresent.ContainsKey($categoryName)) {
|
|
# Store the full category object (or create one with default icon for string categories)
|
|
$categoryObj = if ($c -is [string]) { @{Name = $c; Icon = '' } } else { $c }
|
|
$orderedCategories += $categoryObj
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
# For backward compatibility, create category objects from keys
|
|
foreach ($catName in $categoriesPresent.Keys) {
|
|
$orderedCategories += @{Name = $catName; Icon = '' }
|
|
}
|
|
}
|
|
|
|
foreach ($categoryObj in $orderedCategories) {
|
|
$categoryName = $categoryObj.Name
|
|
|
|
# Create/get card for this category
|
|
$panel = GetOrCreateCategoryCard -categoryObj $categoryObj
|
|
if (-not $panel) { continue }
|
|
|
|
# Collect groups and features for this category, then sort by priority
|
|
$categoryItems = @()
|
|
|
|
# Add any groups for this category
|
|
if ($featuresJson.UiGroups) {
|
|
$groupIndex = 0
|
|
foreach ($group in $featuresJson.UiGroups) {
|
|
if ($group.Category -ne $categoryName) { $groupIndex++; continue }
|
|
$categoryItems += [PSCustomObject]@{
|
|
Type = 'group'
|
|
Data = $group
|
|
Priority = if ($null -ne $group.Priority) { $group.Priority } else { [int]::MaxValue }
|
|
OriginalIndex = $groupIndex
|
|
}
|
|
$groupIndex++
|
|
}
|
|
}
|
|
|
|
# Add individual features for this category
|
|
$featureIndex = 0
|
|
foreach ($feature in $featuresJson.Features) {
|
|
if ($feature.Category -ne $categoryName) { $featureIndex++; continue }
|
|
|
|
# Check version and feature compatibility using Features.json
|
|
if (($feature.MinVersion -and $WinVersion -lt $feature.MinVersion) -or ($feature.MaxVersion -and $WinVersion -gt $feature.MaxVersion) -or ($feature.FeatureId -eq 'DisableModernStandbyNetworking' -and (-not $script:ModernStandbySupported))) {
|
|
$featureIndex++; continue
|
|
}
|
|
|
|
# Skip if feature part of a group
|
|
$inGroup = $false
|
|
if ($featuresJson.UiGroups) {
|
|
foreach ($g in $featuresJson.UiGroups) { foreach ($val in $g.Values) { if ($val.FeatureIds -contains $feature.FeatureId) { $inGroup = $true; break } }; if ($inGroup) { break } }
|
|
}
|
|
if ($inGroup) { $featureIndex++; continue }
|
|
|
|
$categoryItems += [PSCustomObject]@{
|
|
Type = 'feature'
|
|
Data = $feature
|
|
Priority = if ($null -ne $feature.Priority) { $feature.Priority } else { [int]::MaxValue }
|
|
OriginalIndex = $featureIndex
|
|
}
|
|
$featureIndex++
|
|
}
|
|
|
|
# Sort by priority first, then by original index for items with same/no priority
|
|
$sortedItems = $categoryItems | Sort-Object -Property Priority, OriginalIndex
|
|
|
|
# Render sorted items
|
|
foreach ($item in $sortedItems) {
|
|
if ($item.Type -eq 'group') {
|
|
$group = $item.Data
|
|
$items = @('No Change') + ($group.Values | ForEach-Object { $_.Label })
|
|
$comboName = 'Group_{0}Combo' -f $group.GroupId
|
|
$combo = CreateLabeledCombo -parent $panel -labelText $group.Label -comboName $comboName -items $items
|
|
# attach tooltip from UiGroups if present
|
|
if ($group.ToolTip) {
|
|
$tipBlock = New-Object System.Windows.Controls.TextBlock
|
|
$tipBlock.Text = $group.ToolTip
|
|
$tipBlock.TextWrapping = 'Wrap'
|
|
$tipBlock.MaxWidth = 420
|
|
$combo.ToolTip = $tipBlock
|
|
$lblBorderObj = $null
|
|
try { $lblBorderObj = $Window.FindName("$comboName`_LabelBorder") } catch {}
|
|
if ($lblBorderObj) { $lblBorderObj.ToolTip = $tipBlock }
|
|
}
|
|
$script:UiControlMappings[$comboName] = @{ Type = 'group'; Values = $group.Values; Label = $group.Label; Category = $categoryName }
|
|
}
|
|
elseif ($item.Type -eq 'feature') {
|
|
$feature = $item.Data
|
|
$opt = 'Apply'
|
|
if ($feature.FeatureId -match '^Disable') { $opt = 'Disable' } elseif ($feature.FeatureId -match '^Enable') { $opt = 'Enable' }
|
|
$items = @('No Change', $opt)
|
|
$comboName = ("Feature_{0}_Combo" -f $feature.FeatureId) -replace '[^a-zA-Z0-9_]', ''
|
|
$combo = CreateLabeledCombo -parent $panel -labelText $feature.Label -comboName $comboName -items $items
|
|
# attach tooltip from Features.json if present, and include the disabled-state reason
|
|
if ($feature.ToolTip -or $feature.DisableWhenApplied -eq $true) {
|
|
$tooltipText = $feature.ToolTip
|
|
if ($feature.DisableWhenApplied -eq $true) {
|
|
$tooltipText = "This tweak is already applied and cannot be undone automatically. Visit the Win11Debloat wiki for instructions on how to manually revert this change."
|
|
}
|
|
|
|
$tipBlock = New-Object System.Windows.Controls.TextBlock
|
|
$tipBlock.Text = $tooltipText
|
|
$tipBlock.TextWrapping = 'Wrap'
|
|
$tipBlock.MaxWidth = 420
|
|
$combo.ToolTip = $tipBlock
|
|
[System.Windows.Controls.ToolTipService]::SetShowOnDisabled($combo, $true)
|
|
$lblBorderObj = $null
|
|
try { $lblBorderObj = $Window.FindName("$comboName`_LabelBorder") } catch {}
|
|
if ($lblBorderObj) { $lblBorderObj.ToolTip = $tipBlock }
|
|
}
|
|
$script:UiControlMappings[$comboName] = @{ Type = 'feature'; FeatureId = $feature.FeatureId; Label = $feature.Label; Category = $categoryName }
|
|
}
|
|
}
|
|
}
|
|
|
|
# Build a feature-label lookup so GenerateOverview can resolve feature IDs without reloading JSON
|
|
$script:FeatureLabelLookup = @{}
|
|
$script:UndoFeatureLabelLookup = @{}
|
|
foreach ($f in $featuresJson.Features) {
|
|
$script:FeatureLabelLookup[$f.FeatureId] = $f.Label
|
|
$script:UndoFeatureLabelLookup[$f.FeatureId] = $f.UndoLabel
|
|
}
|
|
}
|
|
|
|
function Update-CurrentTweakSystemState {
|
|
param(
|
|
[System.Windows.Window]$Window,
|
|
[bool]$ApplyToUi
|
|
)
|
|
|
|
if (-not $script:UiControlMappings) { return }
|
|
if (-not $script:Features) { return }
|
|
|
|
$featuresJson = LoadJsonFile -filePath $script:FeaturesFilePath -expectedVersion "1.0"
|
|
if (-not $featuresJson) { return }
|
|
|
|
$groupMap = @{}
|
|
if ($featuresJson.UiGroups) {
|
|
foreach ($g in $featuresJson.UiGroups) {
|
|
$groupMap[$g.GroupId] = $g
|
|
}
|
|
}
|
|
|
|
foreach ($controlName in $script:UiControlMappings.Keys) {
|
|
$control = $Window.FindName($controlName)
|
|
if (-not $control) { continue }
|
|
$mapping = $script:UiControlMappings[$controlName]
|
|
|
|
if ($control -is [System.Windows.Controls.CheckBox] -and $mapping.Type -eq 'feature') {
|
|
$applied = $false
|
|
try { $applied = [bool](Test-FeatureApplied -FeatureId $mapping.FeatureId) } catch {}
|
|
$featureObj = $script:Features[$mapping.FeatureId]
|
|
$disableWhenApplied = $featureObj -and $featureObj.DisableWhenApplied -eq $true
|
|
Add-Member -InputObject $control -MemberType NoteProperty -Name 'SystemState' -Value $applied -Force
|
|
Add-Member -InputObject $control -MemberType NoteProperty -Name 'DisableWhenApplied' -Value $disableWhenApplied -Force
|
|
|
|
if ($ApplyToUi) {
|
|
$control.IsChecked = $applied
|
|
$control.IsEnabled = -not ($applied -and $disableWhenApplied)
|
|
Add-Member -InputObject $control -MemberType NoteProperty -Name 'InitialState' -Value $applied -Force
|
|
}
|
|
}
|
|
elseif ($control -is [System.Windows.Controls.ComboBox] -and $mapping.Type -eq 'group') {
|
|
$groupId = $null
|
|
if ($controlName -match '^Group_(.+)Combo$') { $groupId = $matches[1] }
|
|
$activeIndex = 0
|
|
if ($groupId -and $groupMap.ContainsKey($groupId)) {
|
|
try { $activeIndex = Get-CurrentGroupActiveIndex -Group $groupMap[$groupId] } catch {}
|
|
}
|
|
Add-Member -InputObject $control -MemberType NoteProperty -Name 'SystemIndex' -Value $activeIndex -Force
|
|
|
|
if ($ApplyToUi) {
|
|
$control.SelectedIndex = $activeIndex
|
|
Add-Member -InputObject $control -MemberType NoteProperty -Name 'InitialIndex' -Value $activeIndex -Force
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function Load-CurrentTweakStateIntoUI {
|
|
param([System.Windows.Window]$Window)
|
|
|
|
Update-CurrentTweakSystemState -Window $Window -ApplyToUi:$true
|
|
}
|
|
|
|
function Reset-TweaksToSystemState {
|
|
param(
|
|
[System.Windows.Window]$Window,
|
|
[bool]$LoadSystemState
|
|
)
|
|
|
|
if (-not $script:UiControlMappings) { return }
|
|
|
|
foreach ($controlName in $script:UiControlMappings.Keys) {
|
|
$control = $Window.FindName($controlName)
|
|
if (-not $control) { continue }
|
|
|
|
if ($control -is [System.Windows.Controls.CheckBox]) {
|
|
if ($LoadSystemState) {
|
|
# Set checkbox to the currently applied state from registry
|
|
$applied = if ($null -ne $control.PSObject.Properties['SystemState']) { [bool]$control.SystemState } else { $false }
|
|
$disableWhenApplied = $null -ne $control.PSObject.Properties['DisableWhenApplied'] -and [bool]$control.DisableWhenApplied
|
|
$control.IsChecked = $applied
|
|
$control.IsEnabled = -not ($applied -and $disableWhenApplied)
|
|
Add-Member -InputObject $control -MemberType NoteProperty -Name 'InitialState' -Value $applied -Force
|
|
}
|
|
else {
|
|
# Clear the checkbox
|
|
$control.IsChecked = $false
|
|
$control.IsEnabled = $true
|
|
Add-Member -InputObject $control -MemberType NoteProperty -Name 'InitialState' -Value $false -Force
|
|
}
|
|
}
|
|
elseif ($control -is [System.Windows.Controls.ComboBox]) {
|
|
if ($LoadSystemState) {
|
|
# Set combobox to the currently applied state from registry
|
|
$idx = if ($null -ne $control.PSObject.Properties['SystemIndex']) { [int]$control.SystemIndex } else { 0 }
|
|
$control.SelectedIndex = $idx
|
|
Add-Member -InputObject $control -MemberType NoteProperty -Name 'InitialIndex' -Value $idx -Force
|
|
}
|
|
else {
|
|
# Reset to first item (No Change)
|
|
$control.SelectedIndex = 0
|
|
Add-Member -InputObject $control -MemberType NoteProperty -Name 'InitialIndex' -Value 0 -Force
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function Update-TweaksResponsiveColumns {
|
|
param([System.Windows.Window]$Window)
|
|
|
|
$tweaksGrid = $Window.FindName('TweaksGrid')
|
|
$col0 = $Window.FindName('Column0Panel')
|
|
$col1 = $Window.FindName('Column1Panel')
|
|
$col2 = $Window.FindName('Column2Panel')
|
|
|
|
if (-not $tweaksGrid -or -not $col0 -or -not $col1 -or -not $col2) { return }
|
|
if ($tweaksGrid.ColumnDefinitions.Count -lt 3) { return }
|
|
if ($null -eq $script:TweaksCardsMovedFromCol2) { $script:TweaksCardsMovedFromCol2 = @() }
|
|
|
|
$useTwoColumns = $Window.ActualWidth -lt 1200
|
|
if ($script:TweaksCompactMode -eq $useTwoColumns) { return }
|
|
$script:TweaksCompactMode = $useTwoColumns
|
|
|
|
if ($useTwoColumns) {
|
|
$tweaksGrid.ColumnDefinitions[0].Width = [System.Windows.GridLength]::new(1, [System.Windows.GridUnitType]::Star)
|
|
$tweaksGrid.ColumnDefinitions[1].Width = [System.Windows.GridLength]::new(1, [System.Windows.GridUnitType]::Star)
|
|
$tweaksGrid.ColumnDefinitions[2].Width = [System.Windows.GridLength]::new(0)
|
|
$col2.Visibility = 'Collapsed'
|
|
|
|
# Move third-column cards once when entering compact mode.
|
|
$cardsToMove = @($col2.Children) | Where-Object { $_ -is [System.Windows.UIElement] }
|
|
$script:TweaksCardsMovedFromCol2 = @($cardsToMove)
|
|
$col2.Children.Clear()
|
|
$targetColumns = @($col0, $col1)
|
|
foreach ($card in $cardsToMove) {
|
|
$target = $targetColumns |
|
|
Sort-Object @{Expression = { $_.Children.Count }; Ascending = $true }, @{Expression = { $targetColumns.IndexOf($_) }; Ascending = $true } |
|
|
Select-Object -First 1
|
|
$target.Children.Add($card) | Out-Null
|
|
}
|
|
return
|
|
}
|
|
|
|
$tweaksGrid.ColumnDefinitions[0].Width = [System.Windows.GridLength]::new(1, [System.Windows.GridUnitType]::Star)
|
|
$tweaksGrid.ColumnDefinitions[1].Width = [System.Windows.GridLength]::new(1, [System.Windows.GridUnitType]::Star)
|
|
$tweaksGrid.ColumnDefinitions[2].Width = [System.Windows.GridLength]::new(1, [System.Windows.GridUnitType]::Star)
|
|
$col2.Visibility = 'Visible'
|
|
|
|
foreach ($card in (@($script:TweaksCardsMovedFromCol2) | Where-Object { $_ -is [System.Windows.UIElement] })) {
|
|
if ($col0.Children.Contains($card)) {
|
|
$col0.Children.Remove($card) | Out-Null
|
|
}
|
|
elseif ($col1.Children.Contains($card)) {
|
|
$col1.Children.Remove($card) | Out-Null
|
|
}
|
|
$col2.Children.Add($card) | Out-Null
|
|
}
|
|
$script:TweaksCardsMovedFromCol2 = @()
|
|
}
|
|
|
|
function Clear-TweakSelections {
|
|
param([System.Windows.Window]$Window)
|
|
|
|
if (-not $script:UiControlMappings) { return }
|
|
|
|
foreach ($controlName in $script:UiControlMappings.Keys) {
|
|
$control = $Window.FindName($controlName)
|
|
if ($control -is [System.Windows.Controls.CheckBox]) {
|
|
$control.IsChecked = $false
|
|
$control.IsEnabled = $true
|
|
}
|
|
elseif ($control -is [System.Windows.Controls.ComboBox]) {
|
|
$control.SelectedIndex = 0
|
|
}
|
|
}
|
|
}
|
|
|
|
function Clear-TweakHighlights {
|
|
param([System.Windows.Window]$Window)
|
|
|
|
$col0 = $Window.FindName('Column0Panel')
|
|
$col1 = $Window.FindName('Column1Panel')
|
|
$col2 = $Window.FindName('Column2Panel')
|
|
$columns = @($col0, $col1, $col2) | Where-Object { $_ -ne $null }
|
|
foreach ($column in $columns) {
|
|
foreach ($card in $column.Children) {
|
|
if ($card -is [System.Windows.Controls.Border] -and $card.Child -is [System.Windows.Controls.StackPanel]) {
|
|
foreach ($control in $card.Child.Children) {
|
|
if ($control -is [System.Windows.Controls.CheckBox] -or
|
|
($control -is [System.Windows.Controls.Border] -and $control.Name -like '*_LabelBorder')) {
|
|
$control.Background = [System.Windows.Media.Brushes]::Transparent
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function Test-ComboBoxContainsMatch {
|
|
param ([System.Windows.Controls.ComboBox]$ComboBox, [string]$SearchText)
|
|
|
|
foreach ($item in $ComboBox.Items) {
|
|
$itemText = if ($item -is [System.Windows.Controls.ComboBoxItem]) { $item.Content.ToString().ToLower() } else { $item.ToString().ToLower() }
|
|
if ($itemText.Contains($SearchText)) { return $true }
|
|
}
|
|
return $false
|
|
}
|