2013-05-28 153 views
1

我有一个简单的自定义控件,我有一个ControlTemplate为。我似乎无法从控制台上的Button获取命令,以便路由至其TemplatedParent的命令。路由命令模板父

<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

您绑定属性路径SaveButton.Button,其中TemplatedParent作为源。因此,您的绑定源是您正在模板化的按钮,但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控制在你的SaveButton模板里面。我认为你应该只重新模拟按钮的外观,但行为已经存在,你不需要Button中的Button。您可以简单地使用您正在模板化的Button的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}”/> 将是可取的,但该命令似乎没有在窗口的ViewModel中处理SaveButton。我可以看到(在snoop中)控件的DataContext实际上是Window的DataContext。它只是不调用ViewModel中的DelegateCommand。 public DelegateCommand 保存{get;私人设置; } Save = new DelegateCommand (x => { Debug.WriteLine(“Save Clicked!”); }); – Flea

+0

同意。我的首选是重新做按钮的视觉风格。我是一个新手,所以我不确定如何做到这一点,只需将该复选标记添加到按钮的右上角。如果你有这方面的建议,我愿意接受。 – Flea

+0

@Flea它应该很简单,只需从模板中删除按钮,而不是Button放置一个ContentPresenter控件。所有应该工作,您的ContentPresenter将显示在按钮上设置的内容,并且您的SaveButton上的绑定设置的命令应该工作。 – jure