在 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;
}
}
}
我编写了以下 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;
}
}
}