为了理解绑定是如何工作的,我实现了从FrameworkElement派生的MyContainer。此容器允许设置Children并将它们添加到逻辑树中。但是ElementName的绑定不起作用。我可以使用MyContainer使其工作,将父级保留为FrameworkElement吗?
C#:
public class MyContainer : FrameworkElement
{
public MyContainer()
{
Children = new List<FrameworkElement>();
}
public List<FrameworkElement> Children { get; set; }
protected override IEnumerator LogicalChildren
{
get { return Children.GetEnumerator(); }
}
}
XAML:
<Window x:Class="WpfLogicalTree.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfLogicalTree"
Title="Window1" Height="300" Width="300">
<StackPanel>
<local:MyContainer>
<local:MyContainer.Children>
<TextBlock Text="Foo" x:Name="_source" />
<TextBlock Text="{Binding Path=Text, ElementName=_source}" x:Name="_target"/>
</local:MyContainer.Children>
</local:MyContainer>
<Button Click="Button_Click">Test</Button>
</StackPanel>
</Window>
Window1.cs
private void Button_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show(_target.Text);
}
答案 0 :(得分:3)
我不必使用LogicalChildren,而是调用AddLogicalChild。所以这有效:
public class MyContainer : FrameworkElement
{
public MyContainer()
{
Children = new List<FrameworkElement>();
this.Loaded += new RoutedEventHandler(OnLoaded);
}
void OnLoaded(object sender, RoutedEventArgs e)
{
foreach (FrameworkElement fe in Children)
this.AddLogicalChild(fe);
}
public List<FrameworkElement> Children { get; set; }
}
AddLogicalChild设置元素的逻辑父元素,这是查找注册了“_source”名称的NameScope所必需的。在我们的例子中,名称范围是Window1。
请注意。 AddLogicalChild不会导致LogicalChildren自动返回我们的子节点,它只会设置Parent。所以LogicalTreeHelper.GetChildren将是空集合。但我们在这里不需要它。