Function New-XamlWindow {
    <#
    .SYNOPSIS
        Loads a XAML file and creates a WPF window object.

    .DESCRIPTION
        This function reads a XAML file, cleans it for PowerShell compatibility, and loads it into a WPF window object. It also automatically finds all named controls within the XAML and creates PowerShell variables for them, simplifying GUI scripting.

    .PARAMETER XamlFile
        The file path to the .xaml file defining the GUI layout.

    .PARAMETER VariablePrefix
        An optional prefix to add to the auto-generated variables for the GUI controls. This helps avoid variable name conflicts. For example, a prefix 'Main' for a button named 'Submit' would create a variable '$MainSubmit'.

    .EXAMPLE
        $MyWindow, $MyControls = New-XamlWindow -XamlFile 'C:\Scripts\MyGui.xaml' -VariablePrefix 'Main'
        $MainSubmit.add_Click({ $MainWindow.Close() })
        $MyWindow.ShowDialog() | Out-Null
        
        This example loads a XAML file, creates variables for its controls with the prefix 'Main', attaches a click event to the submit button, and displays the window.

    .OUTPUTS
        System.Windows.Window
        An array containing the window object and a hashtable of the controls.
    #>
    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true)]
        [string]$XamlFile,

        [string]$VariablePrefix
    )

    # Ensure PresentationFramework is loaded
    Add-Type -AssemblyName PresentationFramework

    # Read and clean the XAML file
    try {
        $inputXaml = Get-Content -Path $XamlFile -Raw
        $inputXaml = $inputXaml -replace 'mc:Ignorable="d"','' -replace 'x:N','N' -replace '^<Win.*','<Window'
        $xamlFolder = Split-Path -Parent (Resolve-Path $XamlFile)
        $inputXaml = [regex]::Replace($inputXaml, 'Source="([^":]+\.xaml)"', {
            param($match)
            $relativePath = $match.Groups[1].Value
            $resourcePath = Join-Path $xamlFolder $relativePath
            $resourceUri = ([System.Uri]$resourcePath).AbsoluteUri
            return "Source=`"$resourceUri`""
        })
        [xml]$xaml = $inputXaml
    }
    catch {
        Write-Error "Failed to read or parse XAML file '$XamlFile'. Error: $($_.Exception.Message)"
        return
    }

    $reader = (New-Object System.Xml.XmlNodeReader $xaml)
    try {
        $window = [Windows.Markup.XamlReader]::Load($reader)
    }
    catch {
        Write-Error "Failed to load XAML into a window object. Check XAML for errors. Error: $($_.Exception.Message)"
        return
    }

    # Find all named controls and create variables for them
    $controls = @{}
    $xaml.SelectNodes("//*[@Name]") | ForEach-Object {
        $controlName = $_.Name
        $variableName = if ($VariablePrefix) { "$VariablePrefix$controlName" } else { $controlName }
        try {
            $control = $window.FindName($controlName)
            $controls[$controlName] = $control
            Set-Variable -Name $variableName -Value $control -Scope Script
            Write-Verbose "Created script-scoped variable '$($variableName)' for control '$controlName'."
        }
        catch {
            Write-Warning "Could not find or create a variable for control with name: '$controlName'. Error: $($_.Exception.Message)"
        }
    }

    # Return the window object and the hashtable of controls
    return ,($window, $controls)
}
