Abby Fichtner
Abby Fichtner

Reputation: 2648

How do I specify Command on Button when I'm using a Template in WPF?

I have a Button template to define what my edit button should look like:

<ControlTemplate x:Key="EditButton" TargetType="{x:Type Button}">
     <Button Style="{StaticResource GrayOutButtonStyle}" >
        <Image x:Name="editImage" Source="{StaticResource EditIcon}" />
     </Button>
</ControlTemplate>

I want to declare the Command in the XAML where I create the button (not in the template). But when I set the Command attribute in the Button, it's being ignored:

<Button Template="{StaticResource EditButton}" 
        Command="{Binding Source={StaticResource ViewModel}, Path=EditCommand}" 
        CommandParameter="{Binding}" />

What's wrong with my syntax?

(Note: If I remove the template from this button then the Command works, so it's something about using a template that's messing it up.).

Upvotes: 2

Views: 2783

Answers (2)

Malu MN
Malu MN

Reputation: 150

Another option to refer to the command is relative binding as below:

<Setter Property="Template">
    <Setter.Value>
        <ControlTemplate TargetType="Button">
            <Button Command="{Binding Path=Command, RelativeSource={RelativeSource AncestorType=Button}}">
                <Image... />
            </Button>
        </ControlTemplate>
    </Setter.Value>
</Setter>

Upvotes: 0

Kent Boogaart
Kent Boogaart

Reputation: 178820

Why does your Button template include another Button? That makes no sense and would suffer from a StackOverflow if your template was applied implicitly. It should just be the Image, in which case your command should work.

To be clear, what's happening is you have an outer Button which correctly has the ICommand applied to it. However, it's being rendered as another Button with an Image inside it. Hence, when you click the Image, you're actually clicking the inner Button, which has no ICommand associated with it. The outer Button never "sees" the click, so it never executes the command.

Your only other option, which I wouldn't recommend, but should work, is to have the inner button bind to the properties on the outer button:

<ControlTemplate ...>
    <Button Command="{TemplateBinding Command}" CommandParameter="{Binding CommandParameter}" ...>
        <Image .../>
    </Button>
</ControlTemplate>

Upvotes: 1

Related Questions