在 WPF XAML PowerShell 脚本中将 UserControl 添加到 window 的最佳实践

Best practice to add a UserControl to a window in a WPF XAML PowerShell script

我编写了以下 Test.ps1 PowerShell 脚本来显示 WPF GUI:

function LoadXamlFile( $path )
{
    [System.Xml.XmlDocument]$xml = Get-Content -Path $path
    $xmlReader = New-Object -TypeName System.Xml.XmlNodeReader -ArgumentList $xml
    $xaml = [System.Windows.Markup.XamlReader]::Load( $xmlReader )
    return $xaml
}

# Main Window
$MainWindow = LoadXamlFile 'MainWindow.xaml'

# Page 1
$Page1 = LoadXamlFile 'Page1.xaml'

# Is there a cleaner way than the following line to add a UserControl object to the main window?    
$MainWindow.Content = $Page1

$TextBox1 = $MainWindow.Content.FindName('TextBox1')
$TextBox1.Text = 'test'

$MainWindow.ShowDialog()

此脚本需要以下两个 XAML 文件:

MainWindow.xaml

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Name="MainWindow"
    Title="WPF Test" Height="200" Width="400">
</Window>

Page1.xaml

<UserControl
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Name="Page1">
    <Grid>
        <TextBox x:Name="TextBox1" HorizontalAlignment="Center" Height="23" Margin="0,-40,0,0" TextWrapping="Wrap" VerticalAlignment="Center" Width="120"/>
        <Button x:Name="Button1" Content="Next" HorizontalAlignment="Center" Margin="0,40,0,0" VerticalAlignment="Center" Width="76"/>
    </Grid>
</UserControl>

有没有办法将 UserControl 添加到我的主 window 中,这样我就可以找到带有 $TextBox1 = $MainWindow.FindName('TextBox1') 而不是 $TextBox1 = $MainWindow.Content.FindName('TextBox1') 的元素?

$MainWindow.Content = $Page1 是将 UserControl 添加到我的主 window 的正确方法吗?

您可以这样做:$MainWindow.AddChild($Page1) 如果您愿意。

您可以通过索引访问文本框 - 但在我看来这并不是很干净:

# $TextBox1 = $MainWindow.Content.FindName('TextBox1')
# $TextBox1.Text = 'test'
$Page1.Content.Children[0].Text = 'test'

我不确定您希望对您的代码进行何种改进。看起来还不错,除了您使用 PowerShell 来操作 GUI 这一事实之外——在我看来,这几乎总是错误的做事方式。

您不能直接这样做,因为 UserControl 有它自己的 naming scope。如果两次将用户控件添加到主窗口,哪个元素应该使用 FindName 方法 return?

但是,您可以编写自己的方法来遍历可视化树。 这是一个:http://www.codeproject.com/Articles/63157/LINQ-to-Visual-

    public static IEnumerable<UIElement> Descendants(this UIElement element)
    {
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(element); i++)
        {
            var child = VisualTreeHelper.GetChild(element, i) as UIElement;
            if (child == null) continue;
            yield return child;
            foreach (var childOfChild in Descendants(child))
            {
                yield return childOfChild;
            }
        }
    }