2013-08-26 3 views
0

하나의 열거 형 DependencyProperty를 노출하는 사용자 지정 컨트롤 (Control 継承)을 만들었습니다. 기본 컨트롤 템플릿은 요소를 켜거나 끄기 위해 트리거를 사용하여 속성의 선택된 값을 기반으로 다르게 렌더링합니다. 이 컨트롤은 UI에서보기 위해 UserControl에 직접 배치 될 때 매우 효과적입니다. 그러나 컨트롤의 요점은 대형 복합 컨트롤의 일부로 존재하므로 다른 사용자 지정 컨트롤의 ControlTemplate에서도 사용됩니다. 그렇게하면 종속성 속성에 대한 변경 사항이 컨트롤에 의해 인식되지 않습니다. Dependency Property에 PropertyChangedCallback을 추가하고 절대 적중되지 않는 중단 점을 설정하여이를 확인했습니다. 예를 들어템플릿에서 사용할 때 사용자 지정 컨트롤의 속성이 변경되지 않는다

, 나는이 같은 템플릿에 "CustomControl"를 사용 :

(은 DependencyProperty 됨) EnumProperty하지 "EnumValue는"로 변경하고 기본값 남아
<ControlTemplate> 
    <my:CustomControl EnumProperty="EnumValue" /> 
</ControlTemplate> 

. 그리고 내가 말했듯이, DP에 대한 PropertyChangedCallback의 중단 점은 절대로 호출되지 않습니다.

무엇이 누락 되었습니까? 다음은 UPDATE

내 컨트롤의 정리 된 버전입니다 :

public class CustomControl : Control 
{ 
    static CustomControl() 
    { 
     DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomControl), new FrameworkPropertyMetadata(typeof(CustomControl))); 
    } 

    public StandardIcon() 
     : base() 
    { 
     BorderType = BorderType.None; 
    } 

    public static readonly DependencyProperty BorderTypeProperty = DependencyProperty.Register("BorderType", typeof(BorderType), typeof(CustomControl), new PropertyMetadata(BorderType.None)); 

    public BorderType BorderType 
    { 
     get { return (BorderType)GetValue(BorderTypeProperty); } 
     set { SetValue(BorderTypeProperty, value); } 
    } 
} 


<Style TargetType="{x:Type local:CustomControl"> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type local:CustomControl}"> 
       <Border x:Name="Rectangle" 
         BorderBrush="{TemplateBinding Foreground}" 
         BorderThickness="0" 
         HorizontalAlignment="Stretch" 
         VerticalAlignment="Stretch"> 
        <ContentPresenter ContentSource="Content" /> 
       </Border> 

       <ControlTemplate.Triggers> 
        <Trigger Property="BorderType" Value="Rectangle"> 
         <Setter Property="BorderThickness" TargetName="Rectangle" Value="2" /> 
        </Trigger> 
        <Trigger Property="BorderType" Value="RoundedRectangle"> 
         <Setter Property="BorderThickness" TargetName="Rectangle" Value="2" /> 
         <Setter Property="CornerRadius" TargetName="Rectangle" Value="5" /> 
        </Trigger> 
       </ControlTemplate.Triggers> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

그리고 이것은 ControlTemplate이가이 DataTemplate이있는 것을 알 (다른 컨트롤 내에서 사용되는 방식이며,하지 나는 원래 지시했다).

<Style TargetType="{x:Type local:OtherControl}"> 
    <Setter Property="FontFamily" Value="{x:Static theme:StandardFonts.FontFamily}" /> 
    <Setter Property="FontSize" Value="{x:Static theme:StandardFonts.FontSizeXS}" /> 
    <Setter Property="FontWeight" Value="Bold" /> 
    <Setter Property="ContentTemplate"> 
     <Setter.Value> 
      <DataTemplate> 
       <local:CustomControl BorderType="{Binding TemplatedParent.BorderType, RelativeSource={RelativeSource TemplatedParent}}" 
            Foreground="{Binding TemplatedParent.Foreground, RelativeSource={RelativeSource TemplatedParent}}" /> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

후가 다음과 같이 사용된다 : 예상

<controls:OtherControl Foreground="Red" BorderType="Rectangle" /> 

전경 속성이 변경된다. OtherControl의 Foreground를 변경하면 CustomControl의 Foreground가 변경됩니다. 그러나 BorderType 속성은 존중되지 않고 항상 기본 BorderType.None 값으로 렌더링됩니다.

답변

0

ControlTemplate의 부모는 CustomControl이 바인딩 할 수있는 것이 있어야합니다. 그런 다음 템플릿의 CustomControl을 부모 개체에 바인딩합니다.

<ControlTemplate TargetType="{x:Type Button}"> 
    <Border BorderBrush="{TemplateBinding Background}" /> 
</ControlTemplate> 

내와 "대형 복합 제어"및 국경과 버튼을 교체 : 다음 예에서

, 나는 버튼의 배경에 자사의 BorderBrush를 결합하는 버튼, 템플릿에 테두리를 사용하고 있습니다 : CustomControl 그리고 당신은 설정해야합니다 ...

+0

내 업데이 트를 참조하십시오, 나는 이미 당신이 제안하고있는 것을 믿습니다. 차이점은 ControlTemplate (이 경우)이 아니라 DataTemplate에서 컨트롤을 사용하고 있다는 것을 알았습니다. 어떤 차이가 있는지 확실하지 않습니다. – SonOfPirate

+0

CustomControl이 TemplatedParent의 TemplatedParent BorderType에 바인딩됩니다. 그 부모 컨트롤이 그것의 자식들에게 퍼지는 Foreground 속성을 가지고 있기 때문에 전경 변화를 추측하고 있습니다. "TemplatedParent"를 제거해보십시오. 바인딩 경로의 시작 부분에서 ... – Nick

+0

불행히도 RelativeSource는 실제로 ContentPresenter로, 따라서 두 번째 "홉"으로 해석됩니다. 바인딩 경로의 시작 부분에서 "TemplatedParent"를 제거하면 출력 창에 다음 오류가 나타납니다. BindingExpression 경로 오류 : 'BorderType'속성이 'object'에 없습니다. ''ContentPresenter ' – SonOfPirate