MyContainer, полученный из FrameworkElement с поддержкой привязки - PullRequest
2 голосов
/ 05 апреля 2009

Чтобы понять, как работает привязка, я реализовал MyContainer, производный от FrameworkElement. Этот контейнер позволяет устанавливать дочерние элементы и добавляет их в логическое дерево. Но привязка 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 Ответ

3 голосов
/ 05 апреля 2009

Вместо использования 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 устанавливает логического родителя элемента, это необходимо для поиска NameScope, в котором было зарегистрировано имя "_source". В нашем случае область имен - это Window1.

Примечание. AddLogicalChild не приведет к тому, что LogicalChildren автоматически возвращает наших детей, он только устанавливает Parent. Так что LogicalTreeHelper.GetChildren будет пустой коллекцией. Но нам это здесь не нужно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...