ContentControl在WPF中的交互触发器中命名为CommandParameter

时间:2016-10-19 09:54:25

标签: wpf button triggers

我在内容控件上有几个按钮,我想知道何时按下并释放它们。从我的研究中我发现,唯一的方法是使用交互触发器,但如果有更简单的方法,请纠正我。

由于我有10个以上的按钮,并且分配PreviewMouseLeftButtonDown PreviewMouseLeftButtonUp每个按钮最多需要8行,我定义了一个自定义按钮,我可以在我的UserControl.Resources中重复使用这个按钮:

<UserControl.Resources>
    <Button x:Key="ButtonWTriggers" x:Shared="False">
        <inter:Interaction.Triggers>
            <inter:EventTrigger EventName="PreviewMouseLeftButtonDown">
                <inter:InvokeCommandAction Command="{Binding ButtonDownCmd}" CommandParameter="{Binding Path=Name, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContentControl}}}"/>
            </inter:EventTrigger>
            <inter:EventTrigger EventName="PreviewMouseLeftButtonUp">
                <inter:InvokeCommandAction Command="{Binding ButtonUpCmd}" CommandParameter="{Binding Path=Name, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContentControl}}}"/>
            </inter:EventTrigger>
        </inter:Interaction.Triggers>
    </Button>    
</UserControl.Resources>

<ContentControl Name="testbutton" Content="{StaticResource ButtonWTriggers}"/>

然后我将其用于:

<ContentControl Name="testbutton" Content="{StaticResource ButtonWTriggers}"/>

由于资源被多次使用,并且我想确切地知道按下了哪个按钮,我正在考虑使用ContentControl Name=<NAME HERE>作为命令的参数。我尝试用CommandParameter="{Binding Path=Name, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContentControl}}}"获取该名称,但它不起作用。执行Press和Release的操作但参数为空,可能是因为它试图获取按钮中的name属性而不是内容控件权限?

有人可以帮我将ContentControl的名称作为触发器命令的参数吗?

1 个答案:

答案 0 :(得分:1)

解决问题的一种方法是使用RelativeSource.AncestorLevel属性跳过Button本身:

<inter:InvokeCommandAction (...) CommantParameter="{Binding Name, RelativeSource={RelativeSource AncestorType=ContentControl, AncestorLevel=2}}" />

但我认为这非常不可靠,因为如果例如Button的模板包含ContentControl(相对来源将再次解析为Button本身),它将停止工作。

我认为更可靠的解决方案是将Button.Tag属性绑定到其祖先的名称,然后将InvokeCommandAction.CommandParameter绑定到该属性:

<Button (...) Tag="{Binding Name, RelativeSource={RelativeSource AncestorType=ContentControl}}">
    (...)
    <inter:InvokeCommandAction (...) CommandParameter="{Binding Tag, RelativeSource={RelativeSource AncestorType=Button}}" />
    (...)
</Button>

但是,如果您已将Button.Tag属性用于其他内容,则中间解决方案是使用Button.Parent属性:

<inter:InvokeCommandAction (...) CommantParameter="{Binding Parent.Name, RelativeSource={RelativeSource AncestorType=Button}}" />

请注意,尽管这些方法在您的特定情况下是等效的,但它们在一般情况下并不相同,所以请明智地选择。