因此,在下面的示例代码中,我创建了一个 UserControl UserControldChild,它是主窗口 Window1.xaml 的子窗口。为什么FindName()
方法在下面的代码中找不到“myButton”?
这一定与WPF XAML 名称范围,但我还没有找到关于 NameScope 如何工作的很好的解释。有人可以启发我吗?
//(xml) Window1.xaml
<Window x:Class="VisualTreeTestApplication.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:VisualTreeTestApp="clr-namespace:VisualTreeTestApplication"
Title="Window1" Height="400" Width="400">
<Grid>
<VisualTreeTestApp:UserControlChild/>
</Grid>
</Window>
//(c#) Window1.xaml.cs
namespace VisualTreeTestApplication
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
Button btnTest = (Button)Application.Current.MainWindow.FindName("myButton");
// btnTest is null!
}
}
}
下面的用户控件:
//(wpf) UserControlChild.xaml
<UserControl x:Class="VisualTreeTestApplication.UserControlChild"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="300" Width="300">
<Grid x:Name="myGrid">
<Button x:Name="myButton" Margin="20" >Button</Button>
</Grid>
</UserControl>
//(c#) UserControlChild.xaml.cs (no changes)
namespace VisualTreeTestApplication
{
/// <summary>
/// Interaction logic for UserControlChild.xaml
/// </summary>
public partial class UserControlChild : UserControl
{
public UserControlChild()
{
InitializeComponent();
}
}
}
如果没有正确回答这个问题,我找到了使用 FindName() 记录的替代方法在这里的帖子中.
您是对的 - 这与 XAML 名称范围有关。
这在(有点糟糕)记录在XAML 名称范围页面的名称相关 API 部分.
基本上,如果您有 FrameworkElement 或 FrameworkContentElement,它将定义自己的名称范围。如果您对没有名称范围的类型调用 FindName(),WPF 会进行搜索up直到找到定义名称范围的元素,然后在该名称范围内进行搜索。
在您的情况下,它正在 Window 的名称范围中搜索(它是一个 FrameworkContentElement,因此它定义了自己的范围)。它只搜索该范围内定义的元素。
不过,就您而言,该按钮位于 UserControl 的名称范围内,因此 Window.FindName() 找不到它。没有自动搜索down树进入较低级别的范围。
这是一件好事 - 您的“窗口”不应该知道或不想知道有关它正在使用的 UserControl 的内部细节的任何信息。如果您需要 UserControl 中的属性,则应在 UserControl 级别公开它们 - 让控件管理其自己的子级。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)