mirror of
https://github.com/ChrisTitusTech/winutil.git
synced 2026-08-23 07:56:31 +00:00
* Add Get-WinUtilEntryToolTip helper for preset-key tooltips * Show preset JSON key in app and tweak tooltips * Match apps search against preset key for consistency with tweaks * Limit preset-key tooltips to preset-representable controls Comboboxes and package-manager radio buttons cannot appear in a preset file. Update-WinUtilSelections routes a flat list of keys by the WPFInstall/WPFTweaks/WPFToggle/WPFFeature/WPFAppx prefixes, so a preset can carry neither a combobox selected value nor a radio group choice; WingetRadioButton and ChocoRadioButton do not even carry a WPF prefix. Advertising those control names as preset keys invited users to add keys that fall through the switch and abort the whole import. Revert the combobox label and radio button tooltips to the plain description, and add tests that fail if the key is reattached to a control the preset importer cannot accept. * fix: address preset key review feedback * docs: clarify preset key search scope --------- Co-authored-by: Chris Titus <contact@christitus.com>
559 lines
29 KiB
PowerShell
559 lines
29 KiB
PowerShell
function Invoke-WPFUIElements {
|
|
<#
|
|
.SYNOPSIS
|
|
Adds UI elements to a specified Grid in the WinUtil GUI based on a JSON configuration.
|
|
.PARAMETER configVariable
|
|
The variable/link containing the JSON configuration.
|
|
.PARAMETER targetGridName
|
|
The name of the grid to which the UI elements should be added.
|
|
.PARAMETER columncount
|
|
The number of columns to be used in the Grid. If not provided, a default value is used based on the panel.
|
|
.EXAMPLE
|
|
Invoke-WPFUIElements -configVariable $sync.configs.applications -targetGridName "install" -columncount 5
|
|
.NOTES
|
|
Future me/contributor: If possible, please wrap this into a runspace to make it load all panels at the same time.
|
|
#>
|
|
|
|
param(
|
|
[Parameter(Mandatory, Position = 0)]
|
|
[PSCustomObject]$configVariable,
|
|
|
|
[Parameter(Mandatory, Position = 1)]
|
|
[string]$targetGridName,
|
|
|
|
[Parameter(Mandatory, Position = 2)]
|
|
[int]$columncount
|
|
)
|
|
|
|
$window = $sync.form
|
|
|
|
$borderstyle = $window.FindResource("BorderStyle")
|
|
$HoverTextBlockStyle = $window.FindResource("HoverTextBlockStyle")
|
|
$ColorfulToggleSwitchStyle = $window.FindResource("ColorfulToggleSwitchStyle")
|
|
$ToggleButtonStyle = $window.FindResource("ToggleButtonStyle")
|
|
|
|
if (!$borderstyle -or !$HoverTextBlockStyle -or !$ColorfulToggleSwitchStyle) {
|
|
throw "Failed to retrieve Styles using 'FindResource' from main window element."
|
|
}
|
|
|
|
$targetGrid = $window.FindName($targetGridName)
|
|
|
|
if (!$targetGrid) {
|
|
throw "Failed to retrieve Target Grid by name, provided name: $targetGrid"
|
|
}
|
|
|
|
# Clear existing ColumnDefinitions and Children
|
|
$targetGrid.ColumnDefinitions.Clear() | Out-Null
|
|
$targetGrid.Children.Clear() | Out-Null
|
|
|
|
# Add ColumnDefinitions to the target Grid
|
|
for ($i = 0; $i -lt $columncount; $i++) {
|
|
$colDef = New-Object Windows.Controls.ColumnDefinition
|
|
$colDef.Width = New-Object System.Windows.GridLength([double]1, [System.Windows.GridUnitType]::Star)
|
|
$targetGrid.ColumnDefinitions.Add($colDef) | Out-Null
|
|
}
|
|
|
|
# Convert PSCustomObject to Hashtable
|
|
$configHashtable = @{}
|
|
$configVariable.PSObject.Properties.Name | ForEach-Object {
|
|
$configHashtable[$_] = $configVariable.$_
|
|
}
|
|
|
|
$radioButtonGroups = @{}
|
|
|
|
$organizedData = @{}
|
|
# Iterate through JSON data and organize by panel and category
|
|
foreach ($entry in $configHashtable.Keys) {
|
|
$entryInfo = $configHashtable[$entry]
|
|
|
|
# Create an object for the application
|
|
$entryObject = [PSCustomObject]@{
|
|
Name = $entry
|
|
Category = $entryInfo.Category
|
|
Content = $entryInfo.Content
|
|
Panel = if ($entryInfo.Panel) { $entryInfo.Panel } else { "0" }
|
|
Link = $entryInfo.link
|
|
Description = $entryInfo.description
|
|
Type = $entryInfo.type
|
|
ComboItems = $entryInfo.ComboItems
|
|
ComboDescriptions = $entryInfo.ComboDescriptions
|
|
Registry = $entryInfo.registry
|
|
Checked = $entryInfo.Checked
|
|
ButtonWidth = $entryInfo.ButtonWidth
|
|
GroupName = $entryInfo.GroupName # Added for RadioButton groupings
|
|
}
|
|
|
|
if (-not $organizedData.ContainsKey($entryObject.Panel)) {
|
|
$organizedData[$entryObject.Panel] = @{}
|
|
}
|
|
|
|
if (-not $organizedData[$entryObject.Panel].ContainsKey($entryObject.Category)) {
|
|
$organizedData[$entryObject.Panel][$entryObject.Category] = @()
|
|
}
|
|
|
|
# Store application data in an array under the category
|
|
$organizedData[$entryObject.Panel][$entryObject.Category] += $entryObject
|
|
|
|
}
|
|
|
|
# Initialize panel count
|
|
$panelcount = 0
|
|
|
|
# Iterate through 'organizedData' by panel, category, and application
|
|
$count = 0
|
|
foreach ($panelKey in ($organizedData.Keys | Sort-Object)) {
|
|
# Create a Border for each column
|
|
$border = New-Object Windows.Controls.Border
|
|
$border.VerticalAlignment = "Stretch"
|
|
[System.Windows.Controls.Grid]::SetColumn($border, $panelcount)
|
|
$border.style = $borderstyle
|
|
$targetGrid.Children.Add($border) | Out-Null
|
|
|
|
# Use a DockPanel to contain the content
|
|
$dockPanelContainer = New-Object Windows.Controls.DockPanel
|
|
$border.Child = $dockPanelContainer
|
|
|
|
# Create a StackPanel for application content controls
|
|
$stackPanelContainer = New-Object Windows.Controls.StackPanel
|
|
$stackPanelContainer.HorizontalAlignment = 'Stretch'
|
|
$stackPanelContainer.VerticalAlignment = 'Stretch'
|
|
|
|
# Check if the target grid (or any ancestor) is already inside a ScrollViewer
|
|
$hasOuterScrollViewer = $false
|
|
$currentElement = $targetGrid
|
|
while ($null -ne $currentElement) {
|
|
if ($currentElement -is [System.Windows.Controls.ScrollViewer] -or $currentElement.GetType().Name -eq "ScrollViewer") {
|
|
$hasOuterScrollViewer = $true
|
|
break
|
|
}
|
|
$currentElement = $currentElement.Parent
|
|
}
|
|
|
|
if ($hasOuterScrollViewer) {
|
|
# Add StackPanel directly to DockPanel without nesting a ScrollViewer
|
|
[Windows.Controls.DockPanel]::SetDock($stackPanelContainer, [Windows.Controls.Dock]::Bottom)
|
|
$dockPanelContainer.Children.Add($stackPanelContainer) | Out-Null
|
|
}
|
|
else {
|
|
# Create a ScrollViewer for targets that do not already have an outer ScrollViewer
|
|
$scrollViewer = New-Object Windows.Controls.ScrollViewer
|
|
$scrollViewer.VerticalScrollBarVisibility = "Auto"
|
|
$scrollViewer.HorizontalScrollBarVisibility = "Disabled"
|
|
$scrollViewer.HorizontalAlignment = 'Stretch'
|
|
$scrollViewer.VerticalAlignment = 'Stretch'
|
|
$scrollViewer.Content = $stackPanelContainer
|
|
|
|
[Windows.Controls.DockPanel]::SetDock($scrollViewer, [Windows.Controls.Dock]::Bottom)
|
|
$dockPanelContainer.Children.Add($scrollViewer) | Out-Null
|
|
}
|
|
$panelcount++
|
|
|
|
# Now proceed with adding category labels and entries to $stackPanelContainer
|
|
foreach ($category in ($organizedData[$panelKey].Keys | Sort-Object)) {
|
|
$count++
|
|
|
|
$label = New-Object Windows.Controls.Label
|
|
$categoryCleanName = $category -replace ".*__", ""
|
|
$label.Content = $categoryCleanName
|
|
$label.Focusable = $true
|
|
$label.IsTabStop = $true
|
|
[System.Windows.Automation.AutomationProperties]::SetName($label, $categoryCleanName)
|
|
$label.SetResourceReference([Windows.Controls.Control]::FontSizeProperty, "HeaderFontSize")
|
|
$label.SetResourceReference([Windows.Controls.Control]::FontFamilyProperty, "HeaderFontFamily")
|
|
$label.UseLayoutRounding = $true
|
|
$stackPanelContainer.Children.Add($label) | Out-Null
|
|
$sync[$category] = $label
|
|
|
|
# Sort entries by type (checkboxes first, then buttons, then comboboxes, notes last) and then alphabetically by Content
|
|
$entries = $organizedData[$panelKey][$category] | Sort-Object @{Expression = {
|
|
switch ($_.Type) {
|
|
'Button' { 1 }
|
|
'Combobox' { 2 }
|
|
'Note' { 3 }
|
|
default { 0 }
|
|
}
|
|
}}, Content
|
|
foreach ($entryInfo in $entries) {
|
|
$count++
|
|
# Create the UI elements based on the entry type
|
|
switch ($entryInfo.Type) {
|
|
"Toggle" {
|
|
$dockPanel = New-Object Windows.Controls.DockPanel
|
|
[System.Windows.Automation.AutomationProperties]::SetName($dockPanel, $entryInfo.Content)
|
|
$checkBox = New-Object Windows.Controls.CheckBox
|
|
$checkBox.Name = $entryInfo.Name
|
|
$checkBox.HorizontalAlignment = "Right"
|
|
$checkBox.UseLayoutRounding = $true
|
|
[System.Windows.Automation.AutomationProperties]::SetName($checkBox, $entryInfo.Content)
|
|
$dockPanel.Children.Add($checkBox) | Out-Null
|
|
$checkBox.Style = $ColorfulToggleSwitchStyle
|
|
|
|
$label = New-Object Windows.Controls.Label
|
|
$label.Content = $entryInfo.Content
|
|
$label.ToolTip = $entryInfo.Description
|
|
$label.HorizontalAlignment = "Left"
|
|
$label.SetResourceReference([Windows.Controls.Control]::FontSizeProperty, "FontSize")
|
|
$label.SetResourceReference([Windows.Controls.Control]::ForegroundProperty, "MainForegroundColor")
|
|
$label.UseLayoutRounding = $true
|
|
$dockPanel.Children.Add($label) | Out-Null
|
|
$stackPanelContainer.Children.Add($dockPanel) | Out-Null
|
|
|
|
$sync[$entryInfo.Name] = $checkBox
|
|
$sync[$entryInfo.Name].IsChecked = (Get-WinUtilToggleStatus $entryInfo.Name)
|
|
|
|
$sync[$entryInfo.Name].Add_Checked({
|
|
[System.Object]$Sender = $args[0]
|
|
Invoke-WPFSelectedCheckboxesUpdate -type "Add" -checkboxName $Sender.name
|
|
# Skip applying tweaks while an import is restoring toggle states
|
|
if (-not $sync.ImportInProgress) {
|
|
Invoke-WinUtilTweaks $Sender.name
|
|
}
|
|
})
|
|
|
|
$sync[$entryInfo.Name].Add_Unchecked({
|
|
[System.Object]$Sender = $args[0]
|
|
Invoke-WPFSelectedCheckboxesUpdate -type "Remove" -checkboxName $Sender.name
|
|
# Skip undoing tweaks while an import is restoring toggle states
|
|
if (-not $sync.ImportInProgress) {
|
|
Invoke-WinUtiltweaks $Sender.name -undo $true
|
|
}
|
|
})
|
|
}
|
|
|
|
"ToggleButton" {
|
|
$toggleButton = New-Object Windows.Controls.Primitives.ToggleButton
|
|
$toggleButton.Name = $entryInfo.Name
|
|
$toggleButton.Content = $entryInfo.Content[1]
|
|
$toggleButton.ToolTip = Get-WinUtilEntryToolTip -Description $entryInfo.Description -Key $entryInfo.Name
|
|
$toggleButton.HorizontalAlignment = "Left"
|
|
$toggleButton.Style = $ToggleButtonStyle
|
|
[System.Windows.Automation.AutomationProperties]::SetName($toggleButton, $entryInfo.Content[0])
|
|
|
|
$toggleButton.Tag = @{
|
|
contentOn = if ($entryInfo.Content.Count -ge 1) { $entryInfo.Content[0] } else { "" }
|
|
contentOff = if ($entryInfo.Content.Count -ge 2) { $entryInfo.Content[1] } else { $contentOn }
|
|
}
|
|
|
|
$stackPanelContainer.Children.Add($toggleButton) | Out-Null
|
|
|
|
$sync[$entryInfo.Name] = $toggleButton
|
|
|
|
$sync[$entryInfo.Name].Add_Checked({
|
|
$this.Content = $this.Tag.contentOn
|
|
})
|
|
|
|
$sync[$entryInfo.Name].Add_Unchecked({
|
|
$this.Content = $this.Tag.contentOff
|
|
})
|
|
|
|
if ($null -eq $sync.Buttons) {
|
|
$sync.Buttons = [System.Collections.Generic.List[PSObject]]::new()
|
|
}
|
|
|
|
if ($sync.Buttons -notcontains $toggleButton.Name) {
|
|
$toggleButton.Add_Click({
|
|
[System.Object]$Sender = $args[0]
|
|
Invoke-WPFButton $Sender.name
|
|
})
|
|
$sync.Buttons.Add($toggleButton.Name) | Out-Null
|
|
}
|
|
}
|
|
|
|
"Combobox" {
|
|
$horizontalStackPanel = New-Object Windows.Controls.StackPanel
|
|
$horizontalStackPanel.Orientation = "Horizontal"
|
|
$horizontalStackPanel.Margin = "0,5,0,0"
|
|
[System.Windows.Automation.AutomationProperties]::SetName($horizontalStackPanel, $entryInfo.Content)
|
|
|
|
$label = New-Object Windows.Controls.Label
|
|
$label.Content = $entryInfo.Content
|
|
$label.HorizontalAlignment = "Left"
|
|
$label.ToolTip = $entryInfo.Description
|
|
$label.VerticalAlignment = "Center"
|
|
$label.SetResourceReference([Windows.Controls.Control]::FontSizeProperty, "ButtonFontSize")
|
|
$label.UseLayoutRounding = $true
|
|
$horizontalStackPanel.Children.Add($label) | Out-Null
|
|
|
|
$comboBox = New-Object Windows.Controls.ComboBox
|
|
$comboBox.Name = $entryInfo.Name
|
|
$comboBox.SetResourceReference([Windows.Controls.Control]::HeightProperty, "ButtonHeight")
|
|
$comboBox.SetResourceReference([Windows.Controls.Control]::WidthProperty, "ButtonWidth")
|
|
$comboBox.HorizontalAlignment = "Left"
|
|
$comboBox.VerticalAlignment = "Center"
|
|
$comboBox.SetResourceReference([Windows.Controls.Control]::MarginProperty, "ButtonMargin")
|
|
$comboBox.SetResourceReference([Windows.Controls.Control]::FontSizeProperty, "ButtonFontSize")
|
|
$comboBox.UseLayoutRounding = $true
|
|
$comboBox.Tag = [pscustomobject]@{
|
|
Registry = $entryInfo.Registry
|
|
State = $null
|
|
}
|
|
[System.Windows.Automation.AutomationProperties]::SetName($comboBox, $entryInfo.Content)
|
|
|
|
$comboItems = if ($entryInfo.ComboItems -is [string]) {
|
|
if ($entryInfo.ComboItems.Contains("|")) {
|
|
$entryInfo.ComboItems -split "\|"
|
|
} else {
|
|
$entryInfo.ComboItems -split " "
|
|
}
|
|
} else {
|
|
@($entryInfo.ComboItems)
|
|
}
|
|
|
|
foreach ($comboitem in $comboItems) {
|
|
$comboBoxItem = New-Object Windows.Controls.ComboBoxItem
|
|
$comboBoxItem.Content = $comboitem
|
|
if ($entryInfo.ComboDescriptions) {
|
|
$comboDescription = $entryInfo.ComboDescriptions.PSObject.Properties[$comboitem].Value
|
|
if ($comboDescription) {
|
|
$comboBoxItem.ToolTip = $comboDescription
|
|
}
|
|
}
|
|
$comboBoxItem.SetResourceReference([Windows.Controls.Control]::FontSizeProperty, "ButtonFontSize")
|
|
$comboBoxItem.UseLayoutRounding = $true
|
|
$comboBox.Items.Add($comboBoxItem) | Out-Null
|
|
}
|
|
|
|
$horizontalStackPanel.Children.Add($comboBox) | Out-Null
|
|
$stackPanelContainer.Children.Add($horizontalStackPanel) | Out-Null
|
|
|
|
if ($entryInfo.Registry -and @($entryInfo.Registry)[0].Values) {
|
|
try {
|
|
$comboBox.Tag.State = Get-WinUtilRegistryComboState -Registry $entryInfo.Registry
|
|
$comboBox.SelectedIndex = @($comboBox.Items.Content).IndexOf([string]$comboBox.Tag.State)
|
|
} catch {
|
|
$unknownStateItem = New-Object Windows.Controls.ComboBoxItem
|
|
$unknownStateItem.Content = "Custom / Unknown - select a state"
|
|
$unknownStateItem.IsEnabled = $false
|
|
$unknownStateItem.ToolTip = "$($_.Exception.Message) Select one of the supported states to replace these values."
|
|
$comboBox.Items.Add($unknownStateItem) | Out-Null
|
|
$comboBox.SelectedItem = $unknownStateItem
|
|
$comboBox.ToolTip = $unknownStateItem.ToolTip
|
|
}
|
|
} else {
|
|
$comboBox.SelectedIndex = 0
|
|
}
|
|
|
|
# Set initial text
|
|
if ($comboBox.Items.Count -gt 0) {
|
|
$comboBox.Text = $comboBox.SelectedItem.Content
|
|
}
|
|
|
|
$sync[$entryInfo.Name] = $comboBox
|
|
|
|
# Add SelectionChanged event handler to update the text property
|
|
$comboBox.Add_SelectionChanged({
|
|
$selectedItem = $this.SelectedItem
|
|
if ($selectedItem) {
|
|
$this.Text = $selectedItem.Content
|
|
$registry = $this.Tag.Registry
|
|
if ($registry -and $selectedItem.IsEnabled -and $selectedItem.Content -ne $this.Tag.State) {
|
|
try {
|
|
Set-WinUtilRegistryComboState -Registry $registry -State $selectedItem.Content
|
|
$this.Tag.State = $selectedItem.Content
|
|
$this.ToolTip = $null
|
|
$unknownStateItem = @($this.Items) | Where-Object Content -EQ "Custom / Unknown - select a state" | Select-Object -First 1
|
|
if ($unknownStateItem) {
|
|
$this.Items.Remove($unknownStateItem)
|
|
}
|
|
} catch {
|
|
$applyError = $_.Exception.Message
|
|
if ([string]::IsNullOrWhiteSpace($applyError)) {
|
|
$applyError = "Unable to apply registry state '$($selectedItem.Content)'."
|
|
}
|
|
$previousState = if ($this.Tag.State) { $this.Tag.State } else { "Custom / Unknown - select a state" }
|
|
$this.SelectedItem = @($this.Items) | Where-Object Content -EQ $previousState | Select-Object -First 1
|
|
[System.Windows.MessageBox]::Show(
|
|
$applyError,
|
|
"WinUtil",
|
|
[System.Windows.MessageBoxButton]::OK,
|
|
[System.Windows.MessageBoxImage]::Warning
|
|
) | Out-Null
|
|
}
|
|
}
|
|
}
|
|
})
|
|
|
|
if ($entryInfo.Registry -and @($entryInfo.Registry)[0].Values -and $entryInfo.Link) {
|
|
$textBlock = New-Object Windows.Controls.TextBlock
|
|
$textBlock.Name = $comboBox.Name + "Link"
|
|
$textBlock.Text = "(?)"
|
|
$textBlock.ToolTip = $entryInfo.Link
|
|
$textBlock.Style = $HoverTextBlockStyle
|
|
$textBlock.UseLayoutRounding = $true
|
|
$textBlock.VerticalAlignment = "Center"
|
|
$textBlock.SetResourceReference([Windows.Controls.Control]::FontSizeProperty, "FontSize")
|
|
$textBlock.Tag = $comboBox
|
|
|
|
$textBlock.Add_MouseUp({
|
|
[System.Object]$Sender = $args[0]
|
|
Start-Process $Sender.ToolTip -ErrorAction Stop
|
|
})
|
|
|
|
$horizontalStackPanel.Children.Add($textBlock) | Out-Null
|
|
$sync[$textBlock.Name] = $textBlock
|
|
}
|
|
}
|
|
|
|
"Button" {
|
|
$button = New-Object Windows.Controls.Button
|
|
$button.Name = $entryInfo.Name
|
|
$button.Content = $entryInfo.Content
|
|
$button.HorizontalAlignment = "Left"
|
|
$button.SetResourceReference([Windows.Controls.Control]::MarginProperty, "ButtonMargin")
|
|
$button.SetResourceReference([Windows.Controls.Control]::FontSizeProperty, "ButtonFontSize")
|
|
if ($entryInfo.ButtonWidth) {
|
|
$baseWidth = [int]$entryInfo.ButtonWidth
|
|
$button.Width = [math]::Max($baseWidth, 350)
|
|
}
|
|
[System.Windows.Automation.AutomationProperties]::SetName($button, $entryInfo.Content)
|
|
$stackPanelContainer.Children.Add($button) | Out-Null
|
|
|
|
$sync[$entryInfo.Name] = $button
|
|
|
|
if ($null -eq $sync.Buttons) {
|
|
$sync.Buttons = [System.Collections.Generic.List[PSObject]]::new()
|
|
}
|
|
|
|
if ($sync.Buttons -notcontains $button.Name) {
|
|
$button.Add_Click({
|
|
[System.Object]$Sender = $args[0]
|
|
Invoke-WPFButton $Sender.name
|
|
})
|
|
$sync.Buttons.Add($button.Name) | Out-Null
|
|
}
|
|
}
|
|
|
|
"RadioButton" {
|
|
# Check if a container for this GroupName already exists
|
|
if (-not $radioButtonGroups.ContainsKey($entryInfo.GroupName)) {
|
|
# Create a StackPanel for this group
|
|
$groupStackPanel = New-Object Windows.Controls.StackPanel
|
|
$groupStackPanel.Orientation = "Vertical"
|
|
[System.Windows.Automation.AutomationProperties]::SetName($groupStackPanel, $entryInfo.GroupName)
|
|
$radioButtonGroups[$entryInfo.GroupName] = $groupStackPanel
|
|
|
|
# Add the group container to the ItemsControl
|
|
$stackPanelContainer.Children.Add($groupStackPanel) | Out-Null
|
|
}
|
|
else {
|
|
# Retrieve the existing group container
|
|
$groupStackPanel = $radioButtonGroups[$entryInfo.GroupName]
|
|
}
|
|
|
|
# Create the RadioButton
|
|
$radioButton = New-Object Windows.Controls.RadioButton
|
|
$radioButton.Name = $entryInfo.Name
|
|
$radioButton.GroupName = $entryInfo.GroupName
|
|
$radioButton.Content = $entryInfo.Content
|
|
$radioButton.HorizontalAlignment = "Left"
|
|
$radioButton.SetResourceReference([Windows.Controls.Control]::MarginProperty, "CheckBoxMargin")
|
|
$radioButton.SetResourceReference([Windows.Controls.Control]::FontSizeProperty, "ButtonFontSize")
|
|
$radioButton.ToolTip = $entryInfo.Description
|
|
$radioButton.UseLayoutRounding = $true
|
|
[System.Windows.Automation.AutomationProperties]::SetName($radioButton, $entryInfo.Content)
|
|
|
|
if ($entryInfo.Checked -eq $true) {
|
|
$radioButton.IsChecked = $true
|
|
}
|
|
|
|
# Add the RadioButton to the group container
|
|
$groupStackPanel.Children.Add($radioButton) | Out-Null
|
|
$sync[$entryInfo.Name] = $radioButton
|
|
}
|
|
|
|
"Note" {
|
|
$textBlock = New-Object Windows.Controls.TextBlock
|
|
$textBlock.TextWrapping = "Wrap"
|
|
$textBlock.Margin = "5,5,5,5"
|
|
$textBlock.UseLayoutRounding = $true
|
|
|
|
$bulletBadge = [Windows.Documents.InlineUIContainer]::new((New-WinUtilFossBadge -Size 18 -Round))
|
|
$bulletBadge.BaselineAlignment = [Windows.BaselineAlignment]::Center
|
|
|
|
$textRun = New-Object Windows.Documents.Run
|
|
$textRun.Text = " $($entryInfo.Content)"
|
|
$textRun.SetResourceReference([Windows.Controls.Control]::FontSizeProperty, "FontSize")
|
|
$textRun.Foreground = [Windows.Media.SolidColorBrush]::new([Windows.Media.Color]::FromRgb(19, 143, 83))
|
|
|
|
$textBlock.Inlines.Add($bulletBadge)
|
|
$textBlock.Inlines.Add($textRun)
|
|
|
|
$stackPanelContainer.Children.Add($textBlock) | Out-Null
|
|
}
|
|
|
|
default {
|
|
$horizontalStackPanel = New-Object Windows.Controls.StackPanel
|
|
$horizontalStackPanel.Orientation = "Horizontal"
|
|
[System.Windows.Automation.AutomationProperties]::SetName($horizontalStackPanel, $entryInfo.Content)
|
|
|
|
$checkBox = New-Object Windows.Controls.CheckBox
|
|
$checkBox.Name = $entryInfo.Name
|
|
$checkBox.Content = $entryInfo.Content
|
|
$checkBox.SetResourceReference([Windows.Controls.Control]::FontSizeProperty, "FontSize")
|
|
$checkBox.ToolTip = Get-WinUtilEntryToolTip -Description $entryInfo.Description -Key $entryInfo.Name
|
|
$checkBox.SetResourceReference([Windows.Controls.Control]::MarginProperty, "CheckBoxMargin")
|
|
$checkBox.UseLayoutRounding = $true
|
|
[System.Windows.Automation.AutomationProperties]::SetName($checkBox, $entryInfo.Content)
|
|
if ($entryInfo.Checked -eq $true) {
|
|
$checkBox.IsChecked = $entryInfo.Checked
|
|
}
|
|
$horizontalStackPanel.Children.Add($checkBox) | Out-Null
|
|
|
|
if ($entryInfo.Link) {
|
|
$textBlock = New-Object Windows.Controls.TextBlock
|
|
$textBlock.Name = $checkBox.Name + "Link"
|
|
$textBlock.Text = "(?)"
|
|
$textBlock.ToolTip = $entryInfo.Link
|
|
$textBlock.Style = $HoverTextBlockStyle
|
|
$textBlock.UseLayoutRounding = $true
|
|
|
|
$textBlock.VerticalAlignment = "Center"
|
|
$textBlock.SetResourceReference([Windows.Controls.Control]::FontSizeProperty, "FontSize")
|
|
$textBlock.Tag = $checkBox
|
|
|
|
$textBlock.Add_MouseUp({
|
|
[System.Object]$Sender = $args[0]
|
|
Start-Process $Sender.ToolTip -ErrorAction Stop
|
|
})
|
|
|
|
$updateLinkMargin = {
|
|
[System.Object]$Sender = $args[0]
|
|
$linkedCheckBox = $Sender.Tag
|
|
$MarginTopBase = if ($linkedCheckBox) { $linkedCheckBox.Margin.Top } else { 0 }
|
|
$Sender.Margin = New-Object Windows.Thickness(
|
|
[math]::Round($Sender.FontSize * 0.5),
|
|
($MarginTopBase - [math]::Round($Sender.FontSize / 2)),
|
|
0, 0
|
|
)
|
|
}
|
|
$textBlock.Add_Loaded($updateLinkMargin)
|
|
$fontSizeDescriptor = [System.ComponentModel.DependencyPropertyDescriptor]::FromProperty(
|
|
[Windows.Controls.Control]::FontSizeProperty,
|
|
[Windows.Controls.TextBlock]
|
|
)
|
|
$fontSizeDescriptor.AddValueChanged($textBlock, $updateLinkMargin)
|
|
|
|
$horizontalStackPanel.Children.Add($textBlock) | Out-Null
|
|
|
|
$sync[$textBlock.Name] = $textBlock
|
|
}
|
|
|
|
$stackPanelContainer.Children.Add($horizontalStackPanel) | Out-Null
|
|
$sync[$entryInfo.Name] = $checkBox
|
|
|
|
$sync[$entryInfo.Name].Add_Checked({
|
|
[System.Object]$Sender = $args[0]
|
|
Invoke-WPFSelectedCheckboxesUpdate -type "Add" -checkboxName $Sender.name
|
|
})
|
|
|
|
$sync[$entryInfo.Name].Add_Unchecked({
|
|
[System.Object]$Sender = $args[0]
|
|
Invoke-WPFSelectedCheckboxesUpdate -type "Remove" -checkboxName $Sender.name
|
|
})
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|