2009-04-04 4 views
2

バインディングの仕組みを理解するために、FrameworkElementから派生したMyContainerを実装しました。このコンテナによって、子を設定して論理ツリーに追加することができます。しかし、ElementNameによるバインディングは機能しません。親をFrameworkElementとして残して、MyContainerを使って機能させるにはどうすればよいですか?バインディングサポート付きFrameworkElementから派生したMyContainer

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); 
} 

答えて

3

代わりに、私はAddLogicalChild指定を呼び出す必要があったLogicalChildrenを使用します。だから、この作品:

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は空のコレクションになります。しかし、ここでは必要ありません。

関連する問題