3

나는 다음과 같은 시나리오를 가지고 :Silverlight 사용자 지정 컨트롤 상속. 템플릿 재사용?

[TemplatePart(Name = GoToEditModeButtonPart, Type = typeof(DoubleClickButton))] 
public class ValueBoxWithLabel : ContentControl 
{ 
    public const string GoToEditModeButtonPart = "GoToEditModeButtonPart"; 

    #region LabelText Dependency Property ... 

    #region IsInEditMode Dependency Property ... 

    public event EventHandler<ModeChangedEventArgs> ModeChanged; 

    public ValueBoxWithLabel() 
    { 
     DefaultStyleKey = typeof (ValueBoxWithLabel); 
    } 

    public override void OnApplyTemplate() 
    { 
     base.OnApplyTemplate(); 

     //IsInEditMode invokes ModeChanged in the dependency property 
     ((DoubleClickButton) GetTemplateChild(GoToEditModeButtonPart)).DoubleClick += (sender, args) => IsInEditMode = true; 
    } 

    private void InvokeModeChanged(ModeChangedEventArgs e) 
    { 
     EventHandler<ModeChangedEventArgs> mode = ModeChanged; 
     if (mode != null) 
      mode(this, e); 
    } 
} 

ValueBox 어떤에서 InputBox에 대한 패널 필수적이다. 이제는 간단하지만 응용 프로그램 전체에서 재사용되며 더 복잡한 동작과 레이아웃이 포함됩니다. 입력으로

텍스트 상자 그러므로 내가이 제어하게 사용되는 필수입니다 :

public class TextBoxWithLabel : ValueBoxWithLabel 
{ 
    #region Text Dependency Property ... 

    public TextBoxWithLabel() 
    { 
     DefaultStyleKey = typeof (TextBoxWithLabel); 
    } 
} 

내가 다음 작업을 나던 현재 generic.xaml을을 가지고,하지만 그것은 내가 원하는 무엇의 아이디어 제공 :

ValueBoxWithLabel 이후
<ResourceDictionary> 

<ControlTemplate x:Key="ValueBoxWithLabelTemplate"> 
    <StackPanel Style="{StaticResource ValueBoxWithLabelPanelStyle}"> 
     <TextBlock Style="{StaticResource LabelStyle}" Text="{TemplateBinding LabelText}" /> 
     <Grid> 
      <ContentPresenter Content="{TemplateBinding Content}" /> 
      <local:DoubleClickButton Background="Black" x:Name="GoToEditModeButtonPart"></local:DoubleClickButton> 
     </Grid> 
    </StackPanel> 
</ControlTemplate> 

<Style TargetType="local:ValueBoxWithLabel"> 
    <Setter Property="Template" Value="{StaticResource ValueBoxWithLabelTemplate}" /> 
</Style> 

<Style TargetType="local:TextBoxWithLabel"> 
    <Setter Property="Template" Value="{StaticResource ValueBoxWithLabelTemplate}" /> 
    <Setter Property="Content"> 
     <Setter.Value> 
      <TextBox Style="{StaticResource ValueBoxStyle}" Text="{TemplateBinding Text}" /> 
     </Setter.Value> 
    </Setter> 
</Style> 

대부분의 내가 같은 템플릿을 재사용 이것에 대한 컨트롤을 만들고 싶어 텍스트 상자와 함께 사용됩니다, 그래서 나는,/복사해야 템플릿을 붙여 해달라고 똑같은 변화를 가지고 최신 정보를 유지할 것을 염두에 두십시오.

어떻게 ValueBoxWithLabelTemplate을 재사용하고 나머지 템플릿을 유지하는 콘텐츠 속성 만 재정의 할 수 있습니까?

답변

1

흥미로운 접근 방법입니다. 나는 그것을 직접 시도하지 않았지만 접근법이 효과가있을 것처럼 보인다.

현재 문제는 ContentPresenterContent 속성을 사용하려고한다는 것입니다. 그러나 그것은 컨트롤의 구체적인 인스턴스가 할당되어야합니다.이 경우에는 TextBox을 사용합니다. ControlTemplate의 일부가 아니기 때문에 에 TemplateBinding을 사용할 수 없습니다.

TemplateBinding 문제가 없어도 두 개 이상의 장소에서 TextBox의 동일한 인스턴스를 "재사용"할 수 없기 때문에 어쨌든 하나의 컨트롤 만 만들 수 있습니다. 그것이 우리가 처음부터 템플릿을 가지고있는 이유입니다.

템플리트 템플릿 문제를 해결 모든 방법

는 어렵지 않을 것이다. 정말 속임수는 특수 컨트롤의 내부 내용 컨트롤을 특수 클래스의 속성에 바인딩하는 방법을 찾는 것입니다. TemplateBinding을 사용할 수없는 경우 이렇게하기가 어렵습니다.

먼저 난 그냥 당신이 적어도 컨트롤이 렌더링을 얻기 위해해야 ​​할 변경 내용을 간략하게 설명합니다 : -

<ControlTemplate x:Key="ValueBoxWithLabelTemplate"> 
    <StackPanel Style="{StaticResource ValueBoxWithLabelPanelStyle}"> 
     <TextBlock Style="{StaticResource LabelStyle}" Text="{TemplateBinding LabelText}" /> 
     <Grid> 
      <ContentPresenter ContentTemplate="{TemplateBinding ContentTemplate}" /> 
      <local:DoubleClickButton Background="Black" x:Name="GoToEditModeButtonPart"></local:DoubleClickButton> 
     </Grid> 
    </StackPanel> 
</ControlTemplate> 

TextBoxWithLabel하면된다 : -

<Style TargetType="local:TextBoxWithLabel"> 
    <Setter Property="Template" Value="{StaticResource ValueBoxWithLabelTemplate}" /> 
    <Setter Property="ContentTemplate"> 
     <Setter.Value> 
      <DataTemplate> 
       <TextBox Style="{StaticResource ValueBoxStyle}" /> 
      </DataTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

이 내 생각 (테스트하지 않고) 렌더링합니다.

당신이 누락 된 Text 특성에 바인딩 볼 수

그러나 바인딩 문제.이제이 바인딩 문제를 해결하는 데 도움이 될 수있는 몇 가지 사항을 생각해 볼 수 있지만 DataContext을 악용하거나 ContentPresenter이라는 하위 클래스를 만들어 외부 컨트롤에서 내부 컨트롤로 통과 속성을 도울 수 있습니다. 둘 다 진짜 못생긴다. 같은 간단한 기본 템플릿에 대한

결론

당신은 아마 다시 사용의 어떤 종류를 acheive하는 데 필요한 모든 농구를 통해 점프보다 템플릿을 복제하는 것이 더 낫다.

+0

의견에 감사드립니다. propably 히 이번 주말에 시간을 얻지 않는다. 그러나 나는 그것을 우선 월요일에 시험해보고, 되돌아 간다 :-) –

+0

안녕 다시 anthony. 나는 youre 해결책을 시도하는 것 주위에있다. 그러나 어떤 운도. 문제는 컨트롤 템플릿의 "부품"에 액세스 할 수 없으므로 위의 다음 줄이 작동하지 않습니다. ((DoubleClickButton) GetTemplateChild (GoToEditStateButtonPart))) DoubleClick + = (sender, args) = > IsInEditMode = true; 의견이 있으십니까? –

+0

문제에 대해 많은 조언을드립니다. 현재 프로젝트에 대한 시간 압박으로. 나는 깊이 파고 들어갈 시간이 없었다. 나중에 더 게시 할 수도 있습니다. 개봉 된 주셔서 감사합니다. –

관련 문제