在WPF中使用模板时,如何指定按钮上的命令?

时间:2022-03-08 07:15:20

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:

我想在XAML中声明这个命令,在XAML中我创建了这个按钮(不在模板中)。但是当我在按钮中设置命令属性时,它被忽略了:

<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.).

(注意:如果我从这个按钮中删除模板,那么命令就会起作用,所以它是关于使用一个把它弄乱的模板。)

2 个解决方案

#1


1  

Why does your Button template include another Button? That makes no sense and would suffer from a * 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.

需要说明的是,你有一个外部按钮,它正确地应用了ICommand。然而,它被渲染成另一个按钮,里面有一个图像。因此,当您单击图像时,实际上是单击内部按钮,它没有与之关联的ICommand。外部按钮永远不会“看到”单击,因此它永远不会执行命令。

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>

#2


0  

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>

#1


1  

Why does your Button template include another Button? That makes no sense and would suffer from a * 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.

需要说明的是,你有一个外部按钮,它正确地应用了ICommand。然而,它被渲染成另一个按钮,里面有一个图像。因此,当您单击图像时,实际上是单击内部按钮,它没有与之关联的ICommand。外部按钮永远不会“看到”单击,因此它永远不会执行命令。

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>

#2


0  

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>