2010-08-18 12 views
1

내가이 DependencyProperty로 설정 한 Template 특성을 가진 UserControl 있습니다WPF는 속성을 바인딩 할 수 없습니다,하지만 난 그것을 등록

public partial class TemplateDetail : UserControl 
{ 
    public static readonly DependencyProperty _templateProperty = 
     DependencyProperty.Register(
      "Template", 
      typeof(Template), 
      typeof(TemplateDetail) 
     ); 

    public TemplateDetail() 
    { 
     InitializeComponent(); 
     Template = new Template(); 
     DataContext = Template; 
    } 

    public Template Template 
    { 
     get 
     { 
      return (Template)GetValue(_templateProperty); 
     } 
     set { SetValue(_templateProperty, value); } 
    } 
} 

내가 시도하고를 Window, SaveTemplateDialog의 XAML이 UserControl를 사용하고, 내 SaveTemplateDialog 클래스의 Template 재산의 Template 속성을 설정하기 위해 노력하고있어 :

<local:TemplateDetail HorizontalAlignment="Stretch" VerticalAlignment="Stretch" 
         MinWidth="100" Template="{Binding}" 
         Width="{Binding ElementName=Scroller, Path=ViewportWidth}"/> 

DataContext (SaveTemplateDialog)은 Template 속성으로 설정되며 이는 또한 종속성 속성입니다. 그러나, 위의 XAML에 대한 Template="{Binding}"는 비주얼 스튜디오에서 파란색으로 밑줄과는 말한다 :

타입 A의 '템플릿'속성 'TemplateDetail'을 설정할 수 없습니다 '바인딩'. 'Binding'은 DependencyObject의 DependencyProperty에서만 설정할 수 있습니다. 나는 그것의 값이있는 알고 물론 충분히

, 나는 내 응용 프로그램을로드 할 때, 표시 할 TemplateTemplateDetail 그 시도의 내용이 비어 있습니다. 종속성 속성으로 TemplateDetail.Template을 등록한 경우이 메시지가 표시되는 이유는 무엇입니까?

편집 : 지금은 상당히 혼란 스럽습니다. 나는 또한 값 I을 보여줍니다 SaveTemplateDialog에서이 XAML을 가지고 있기 때문에 올바른 데이터를 받고있다 Path=NewTemplate을 알고

<local:TemplateDetail HorizontalAlignment="Stretch" VerticalAlignment="Stretch" 
         TemplateData="{Binding Path=NewTemplate, Mode=OneWay}" 
         Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="3"/> 

: 내 SaveTemplateDialog 창에서, 나는하여 TemplateDetailUserControl에 템플릿을 따라 통과하는 다음과 같은 일을 해요 NewTemplateMyType 속성에 기대 : TextBlock 내가 기대하는 것을 보여줍니다

<TextBlock Text="{Binding Path=NewTemplate.MyType}" /> 

있다. 그러나 올바른 데이터가 TemplateDetail에 없거나 제대로 바인딩되지 않은 것 같습니다. 왜냐하면 MyType 속성 (또는 다른 Template 속성)을 TemplateDetail에 표시 할 수 없기 때문입니다. TemplateDetail 인 : 지금 여기

<TextBlock Text="{Binding Path=TemplateData.MyType}" Grid.Row="2" Grid.Column="2" 
      HorizontalAlignment="Stretch" Width="200"/> 

그리고 TemplateDetail 클래스의 :

public partial class TemplateDetail : MainWindowUserControl 
{ 
    public static readonly DependencyProperty TemplateDataProperty = 
     DependencyProperty.Register(
      "TemplateData", 
      typeof(Template), 
      typeof(TemplateDetail), 
      new PropertyMetadata(
       new Template("Default Template", null) 
      ) 
     ); 

    public TemplateDetail() 
    { 
     InitializeComponent(); 
     DataContext = this; 
    } 

    public Template TemplateData 
    { 
     get 
     { 
      return (Template)GetValue(TemplateDataProperty); 
     } 
     set { SetValue(TemplateDataProperty, value); } 
    } 
} 
+1

템플릿이 여기에 예약어 인 경우 내 머리 꼭대기에서 잘 모르겠습니다. 다른 이름의 종속성 속성을 시도 했습니까? – Robaticus

+0

@Robaticus :'TemplateDetail.Template' 속성의 이름을'TemplateData'로 변경했습니다. 청색 선을 없애고 구속력을 경고합니다. 내 앱을 실행할 때 여전히 템플릿의 데이터가 표시되지 않지만 다른 문제 일 수 있습니다. 감사! 답변을 추가해야합니다. –

답변

3

당신은 대신 필드와 같은 이름의 PropertyNameProperty처럼 사용할 수있는 표준 규칙을 당신으로하는 DependencyProperty의 이름을 변경해야합니다. XAML에서 항목을 설정하면 SetValue가 호출되고 문자열 이름 (여기서는 "템플릿")과 "속성"을 사용하여 속성의 이름이 지정됩니다. 두 번째 질문에 대한

UPDATE : 바인딩 경로 = NewTemplate의 소스를 일으키는

당신이 당신의 TemplateDetail 생성자에서 DataContext = this을 설정

는 TemplateDetail 컨트롤 자체에 상속 된 DataContext를 변경할 수 있습니다. NewTemplate 속성을 TemplateDetail 유형의 개체에서 찾을 수 없다는 오류가 출력 창에 나타나야합니다.UserControl 자체의 DataContext를 다시 설정하는 대신, 보통 루트 레이아웃 패널에 내 UserControl XAML에 x : Name을 지정하고 생성자에 LayoutRoot.DataContext = this을 대신 설정합니다.

+0

흠. 종속성 속성에 대한 MSDN의 페이지를 참조하여이 작업을 수행했지만 XAML에서 속성을 설정 한 후에 내 응용 프로그램에서 데이터를 속성에 표시하지 않았습니다. 내 응용 프로그램에서는 항상 종속성 속성의 초기 생성자 설정 값을 보여줍니다. 의존성 프로퍼티에서 클래스가'INotifyPropertyChanged'를 구현하도록 시도했지만, 이제는 "A 바인딩을 설정할 수 없습니다 ..."라고 말합니다. –

+1

그건 별개의 문제입니다. 컨트롤의 생성자에서 DP에 대한 기본값을 설정해서는 안됩니다. 대신 PropertyMetadata를 Register에 값 유형에 대한 기본값으로 전달하거나 기본 Style을 통해 적용하십시오. –

+0

@ 존 : 내 의존성 속성의 기본/초기 값이'Register' 호출에서 설정되도록 변경했습니다. 현재 문제로 내 질문을 업데이트했습니다. 감사! –

2

Template이 XAML 프로세서가 혼동을 야기하는 예약어가 아님을 확인하십시오. 다른 단어를 사용해보십시오.

(Sarah Vessel의 제안에 따라 답변으로 게시 됨).

0

나는 뭔가를 업데이트해야한다고 생각합니다. 이 단지 SaveTemplateDialog에서 다음을 가지고 있는게 틀림 없어

public Template NewTemplate 
{ 
    get 
    { 
     return (Template)GetValue(NewTemplateProperty); 
    } 
    set 
    { 
     SetValue(NewTemplateProperty, value); 

     // The magic line, explicitly setting TemplateData property on 
     // the TemplateDetails UserControl: 
     uct_templateDetails.TemplateData = value; 
    } 
} 

: 나는 당시 내 TemplateDetailUserControl 제대로 모든 데이터를 작성하고, 내 SaveTemplateDialog 창에 내 NewTemplate 속성에 다음 그랬다면 내가 기대하는 것을 발견 NewTemplate가 업데이트 될 때마다의 XAML은 TemplateDetails 새 인스턴스를 전송하는 것만으로는 충분하지 않습니다 :

<local:TemplateDetail HorizontalAlignment="Stretch" VerticalAlignment="Stretch" 
         TemplateData="{Binding Path=NewTemplate}" Grid.Row="2" 
         Grid.Column="1" Grid.ColumnSpan="3" 
         x:Name="uct_templateDetails"/> 
내가해야 것처럼 보이지 않기 때문에 내가 잘못 여기서 뭘하는지 지적하는 사람을 사랑

ex SaveTemplateDialog.NewTemplate이 변경 될 때마다 uct_templateDetails.TemplateData = value;라고 명시 적으로 말하십시오. 나는 이것이 업데이트 된 값을 얻기 위해 그것을 사용하는 것들을 일으킬 것이라고 생각했다.

+1

DP 래퍼 속성에 보일러 플레이트 SetValue 호출 이외의 다른 코드를 삽입해서는 안됩니다. 대신 속성 변경 콜백을 사용하십시오. XAML의 모든 호출은 래퍼를 건너 뛰고 SetValue를 직접 호출합니다. 코드에서 GetValue/SetValue를 호출 할 수 있습니다. –

관련 문제