MyContainer派生自FrameworkElement并具有绑定支持

时间:2009-04-04 22:14:54

标签: wpf binding

为了理解绑定是如何工作的,我实现了从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);
}

1 个答案:

答案 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将是空集合。但我们在这里不需要它。