如何在DataTemplate Button中同时使用Command和EventTrigger?

时间:2010-10-11 17:27:02

标签: wpf xaml command datatemplate eventtrigger

我在DataTemplate中有一个Button,它绑定到我的ViewModel中的Command。该按钮还有一个EventTrigger,可以启动一个隐藏编辑控件的Storyboard(按钮是其中的一部分。)

如果我拿起PreviewMouseDown事件,Storyboard工作正常,但Command永远不会被调用。如果我在EventTrigger中拾取MouseDown事件,则命令有效,但故事板不会执行。

如何在点击按钮时同时执行Command和Storyboard?

<Button Content="Save" Command="{Binding SaveCommand}" >
    <Button.Triggers>
        <EventTrigger RoutedEvent="Button.PreviewMouseDown">
            <EventTrigger.Actions>
                <BeginStoryboard Storyboard="{DynamicResource sbCloseTitleEdit}"/>
            </EventTrigger.Actions>
        </EventTrigger>
    </Button.Triggers>
</Button>

3 个答案:

答案 0 :(得分:1)

我通过为包含DataTemplate的ResourceDictionary添加代码隐藏文件,最终解决了我的问题。我不知道这是可能的,但找到了这个解释:

Is it possible to set code behind a resource dictionary in WPF for event handling?

我没有使用EventTrigger来开始隐藏编辑控件的Storyboard,而是在代码隐藏中添加了一个Click处理程序。这有点笨拙,因为我必须找到相对于点击按钮的面板,因为这是唯一可用的参考,但它可以工作。

如果有人有,我们仍在寻找更好的解决方案。

答案 1 :(得分:0)

我尝试了你的代码,我发现它在PreviewMouseDown上的事件触发器上运行正常,只是先执行命令,然后动画才会触发。

继承我的资源

<Storyboard x:Key="sbCloseTitleEdit">
  <ColorAnimation Storyboard.TargetProperty="(Rectangle.Fill).Color" 
                  To="Blue" Duration="0:0:3" Storyboard.TargetName="rect" >
  </ColorAnimation>
</Storyboard>

我的xaml

<Grid>
  <Grid.ColumnDefinitions>
    <ColumnDefinition Width="Auto" />
    <ColumnDefinition Width="Auto" />
  </Grid.ColumnDefinitions>
  <Grid.RowDefinitions>
    <RowDefinition Height="Auto" />
  </Grid.RowDefinitions>
  <Button Content="Save" Command="{Binding SaveCommand}" >
    <Button.Triggers>
      <EventTrigger RoutedEvent="Button.PreviewMouseDown">
        <EventTrigger.Actions>
          <BeginStoryboard 
            Storyboard="{StaticResource sbCloseTitleEdit}"/>
        </EventTrigger.Actions>
      </EventTrigger>
    </Button.Triggers>
  </Button>
  <Rectangle Name="rect" Width="30" Height="30" 
             Grid.Column="1" Fill="Red" />
</Grid>

和我的视图模型

public class MainViewModel
{
    public ActionCommand SaveCommand { get; private set; }
    public MainViewModel()
    {
        SaveCommand = new ActionCommand();
    }
}

public class ActionCommand : ICommand
{
    public void Execute(object parameter)
    {
        // gets fired if event trigger is preview mode
    }

    public bool CanExecute(object parameter)
    {
        return true;
    }

    public event EventHandler CanExecuteChanged;
}
你确定你没有错过什么吗?

答案 2 :(得分:0)

我通过在eventtrigger中调用命令以及您要触发的其他操作来实现此目的:

<Button Command="{Binding AcceptCommand}" Content="Accept">
  <i:Interaction.Triggers>
    <i:EventTrigger EventName="Click">
      <i:InvokeCommandAction Command="{Binding AcceptCommand}"/>
      <triggers:UpdatePropertyAction TargetObject="{Binding RelativeSource={RelativeSource AncestorType={x:Type Controls:ChildWindow}, Mode=FindAncestor}}" TargetProperty="DialogResult" Value="True"  />
    </i:EventTrigger>
  </i:Interaction.Triggers>
</Button>