2013-05-28 8 views
1

나는 ControlTemplate을 가지고있는 간단한 사용자 정의 컨트롤이 있습니다. 나는 그 명령을 TemplatedParent에 라우팅하는 컨트롤의 Button에서 얻을 수없는 것처럼 보입니다.템플릿 부모에게 명령 라우팅

<Style x:Key="SaveButtonStyle" TargetType="{x:Type Controls:SaveButton}"> 
    <Style.Resources> 
     <converters:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter"/> 
    </Style.Resources> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type Controls:SaveButton}"> 
       <DockPanel Width="65" Height="21" LastChildFill="True"> 
        <Canvas DockPanel.Dock="Left" HorizontalAlignment="Right" Margin="0 0 -49 0" ZIndex="1" IsHitTestVisible="False" > 
         <Image Source="Images/green-check.png" Width="16" Height="16" Visibility="{Binding IsDirty, Converter={StaticResource BoolToVisibilityConverter}}" Canvas.Top="-3" RenderOptions.BitmapScalingMode="Fant" /> 
        </Canvas> 
        <Button DockPanel.Dock="Left" HorizontalAlignment="Left" Width="40" Height="21" FontSize="10" 
          Content="{Binding SaveButton.Content, RelativeSource={RelativeSource TemplatedParent}, FallbackValue={x:Static Localization:Strings.Save}}" 
          Command="{Binding SaveButton.Command, RelativeSource={RelativeSource TemplatedParent}}" 
          CommandParameter="{Binding SaveButton.CommandParameter, RelativeSource={RelativeSource TemplatedParent}}" /> 
       </DockPanel> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

이 :

public class SaveButton : Button { 
    public static readonly DependencyProperty IsDirtyProperty = DependencyProperty.Register("IsDirty", typeof(bool), typeof(SaveButton)); 

    static SaveButton() { 
     DefaultStyleKeyProperty.OverrideMetadata(typeof(SaveButton), new FrameworkPropertyMetadata(typeof(SaveButton))); 
    } 

    [Bindable(true), Category("Action")] 
    [Localizability(LocalizationCategory.NeverLocalize)] 
    public bool IsDirty { 
     get { return (bool)GetValue(IsDirtyProperty); } 
     set { SetValue(IsDirtyProperty, value); } 
    } 
} 

및 (결국은) :

<Controls:SaveButton Command="{Binding Save}" IsDirty="{Binding IsDirty}" Style="{DynamicResource SaveButtonStyle}"/> 

흥미로운 부분 IsDirtyContent 바인딩이 제대로 작동하는 것이다. 그것은 작동하지 않는 것처럼 보이는 명령 라우팅 일뿐입니다.

답변

0

TemplatedParent을 원본으로 사용하여 속성 경로 SaveButton.Button에 바인딩하고 있습니다. 따라서 바인딩 소스는 템플리트 할 Button이지만 Button에는 SaveButton 속성이 없습니다.

이 같은 속성 경로에 SaveButton없이 바인딩을 구성하십시오 :

<Button DockPanel.Dock="Left" HorizontalAlignment="Left" Width="40" Height="21" FontSize="10" 
      Content="{Binding Content, RelativeSource={RelativeSource TemplatedParent}, FallbackValue={x:Static Localization:Strings.Save}}" 
      Command="{Binding Command, RelativeSource={RelativeSource TemplatedParent}}" 
      CommandParameter="{Binding CommandParameter, RelativeSource={RelativeSource TemplatedParent}}" /> 

또한, 짧은 구문은 {TemplateBinding..} 확장을 사용할 수 있습니다.

또 다른 이유는 의 템플릿 안에 Button 컨트롤이있는 이유는 무엇입니까? 난 당신이 버튼의 시각적 모양을 retemplate해야한다고 생각하지만, 행동은 이미 거기에, 당신은 버튼 안에 버튼이 필요하지 않습니다. 당신은 단순히 템플릿의 Command 속성을 사용할 수 있습니다.이 명령 라우팅은 필요 없습니다.

편집 :

이 템플릿을

<Style x:Key="SaveButtonStyle" TargetType="{x:Type Controls:SaveButton}"> 
<Style.Resources> 
    <converters:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter"/> 
</Style.Resources> 
<Setter Property="Content" Value="Save"/> 
<Setter Property="Template"> 
    <Setter.Value> 
     <ControlTemplate TargetType="{x:Type Controls:SaveButton}"> 
      <DockPanel Width="65" Height="21" LastChildFill="True"> 
       <Canvas DockPanel.Dock="Left" HorizontalAlignment="Right" Margin="0 0 -49 0" ZIndex="1" IsHitTestVisible="False" > 
        <Image Source="Images/green-check.png" Width="16" Height="16" Visibility="{Binding IsDirty, Converter={StaticResource BoolToVisibilityConverter}}" Canvas.Top="-3" RenderOptions.BitmapScalingMode="Fant" /> 
       </Canvas> 
       <ContentPresenter DockPanel.Dock="Left"/>     
      </DockPanel> 
     </ControlTemplate> 
    </Setter.Value> 
</Setter> 

내용 버튼 스타일 세터에서 설정의 ("저장")를보십시오. 당신은 몇 가지 다른 콘텐츠를 원하는 경우에이처럼 버튼을 사용할 수 있습니다 :

<Controls:SaveButton Content="Something" Command="{Binding Save}" IsDirty="{Binding IsDirty}" Style="{DynamicResource SaveButtonStyle}"/> 
+0

<버튼 ... 명령 = "{TemplateBinding 명령}" CommandParameter = "{TemplateBinding CommandParameter}"/> 것이 바람직 할 것이지만, 명령은 SaveButton이 배치 된 Window의 ViewModel에서 처리되지 않는 것처럼 보입니다. 컨트롤의 DataContext가 실제로 Window의 DataContext라는 것을 알 수 있습니다 (스눕). ViewModel에서 DelegateCommand를 호출하지 않습니다. public DelegateCommand 저장 {get; 개인 집합; } 저장 = 새 DelegateCommand (x => { Debug.WriteLine ("Save Clicked!"); }); – Flea

+0

동의. 내 기본 설정은 버튼의 시각적 스타일을 다시 수행하는 것입니다. 나는 newb이므로 버튼의 오른쪽 상단에 체크 마크를 추가하는 방법은 확실하지 않습니다. 당신이 그것에 대한 제안을한다면, 나는 그것에 열려 있습니다. – Flea

+0

@Flea 간단해야합니다. 그냥 템플릿에서 Button을 제거하고 Button 대신 ContentPresenter 컨트롤을 넣으십시오.모두 작동하면 ContentPresenter에 버튼에 설정된 Content가 표시되고 SaveButton에 바인딩으로 설정된 명령이 작동합니다. – jure