2011-11-30 3 views
1

컨트롤에서 파생 된 자체 ContentControl을 만들어 어두운 WPF 트리 개념을 완전히 이해하려고합니다. 지금은 ContentControl의 논리적 부분 (Content)을 구현했습니다. 뒤에WPF : 바인딩을 찾을 수 없습니다.

내 코드 :

[ContentProperty("Content")] 
public class MyContentControl : Control 
{ 
    public MyContentControl() 
    { 

    } 

    public Object Content 
    { 
     get { return (Object)GetValue(ContentProperty); } 
     set { SetValue(ContentProperty, value); } 
    } 

    public static readonly DependencyProperty ContentProperty = 
     DependencyProperty.Register("Content", typeof(Object), typeof(MyContentControl), new UIPropertyMetadata()); 

} 

XAML :

<StackPanel x:Name="stackPanel"> 
    <TextBlock Visibility="Collapsed" x:Name="textBlock" Text="Hello World"/> 
    <ContentControl> 
     <TextBlock Background="LightBlue" Text="{Binding Text, ElementName=textBlock}"/> 
    </ContentControl> 
    <local:MyContentControl> 
     <TextBlock Text="{Binding Text, ElementName=textBlock}"/> 
    </local:MyContentControl> 
</StackPanel> 

내가 가지고 다음과 같은 바인딩 오류 :

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'ElementName=textBlock'. BindingExpression:Path=Text; DataItem=null; target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')

그것은에 갈 수 없어 내부 TextBlock이 같다 논리적 트리를 찾아 바인딩해야하는 원본 텍스트 블록을 찾습니다. myContentControl을 Content 객체의 부모로 설정할 수 없습니다.

이상형?

감사합니다.

조나스

답변

1

및 FrameworkElement.RemoveLogicalChild ContentChanged을하고 적용 올바르게 바인딩 (검증을 WPF Inspector 포함).

이 모든 내용은 LogicalTree에 대한 것입니다 (xaml 이름 범위는 논리 상위에서 상속 될 수 있습니다). MyContentControl 내의 TextBlock은 MyContentControl.AddLogicalChild (TextBlock)가 호출 될 때 MyContentControl을 부모로 가져옵니다.

내 코드 : 귀하의 답변에 대한

[ContentProperty("Content")] 
public class MyContentControl : Control 
{ 
    public MyContentControl() 
    { 
     Content = new UIElementCollection(this, this); 
    } 


    public Object Content 
    { 
     get { return (Object)GetValue(ContentProperty); } 
     set { SetValue(ContentProperty, value); } 
    } 

    public static readonly DependencyProperty ContentProperty = 
     DependencyProperty.Register("Content", typeof(Object), typeof(MyContentControl), new UIPropertyMetadata(new PropertyChangedCallback(OnContentChanged))); 

    public static void OnContentChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     MyContentControl c = (MyContentControl)d; 

     if (e.OldValue != null) 
     { 
      c.RemoveLogicalChild(e.OldValue); 
     } 

     c.AddLogicalChild(e.NewValue); 
    } 

    protected override System.Collections.IEnumerator LogicalChildren 
    { 
     get 
     { 
      List<Object> l = new List<object>(); 
      if (Content != null) 
       l.Add(Content); 

      return l.GetEnumerator(); 
     } 
    } 
} 
4

관련 질문 : Binding ElementName. Does it use Visual Tree or Logical Tree

다음은 MyContentControl의 동일한 인스턴스 이론적 요소 "TextBlock의는"범위에없는 응용 프로그램에서 다른 곳에서 사용할 수 있기 때문에 가능하지 않다 원하는 바인딩 .

당신이 대신 자원 사용할 수있는 바인딩 이러한 유형의 수행하려는 경우 : 나는 그냥 FrameworkElement.AddLogicalChild을 적용했다

xmlns:clr="clr-namespace:System;assembly=mscorlib" 

<StackPanel> 
    <StackPanel.Resources> 
     <clr:String x:Key="MyText">Hanky Panky</clr:String> 
    </StackPanel.Resources> 
    <TextBlock Text="{StaticResource MyText}" /> 

    <ContentControl> 
     <TextBlock Text="{Binding Source={StaticResource MyText}}" /> 
    </ContentControl> 
</StackPanel> 
+0

감사합니다. 나는 그것에 대해 다시 생각할 필요가 있지만 귀하의 링크는 매우 도움이되었습니다. 내가 xaml 변경하고 싶지 않아하지만 난 정확히 어떻게 ContentControl과 동일한 행동을 할 수있는 waay에 MyContentControl 뒤에 코드를 수정 해야하는지 알고 싶습니다. – Jonas

관련 문제