Как использовать Command и EventTrigger в кнопке DataTemplate?

У меня есть кнопка в DataTemplate, которая привязана к команде в моей модели представления. У кнопки также есть EventTrigger, который запускает раскадровку, скрывающую элементы управления редактированием (частью которых является кнопка).

Раскадровка работает нормально, если я получаю событие PreviewMouseDown, но команда никогда не вызывается. Если я выбираю событие MouseDown в своем EventTrigger, команда работает, но раскадровка не выполняется.

Как сделать так, чтобы и команда, и раскадровка выполнялись при нажатии кнопки?

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

person Bill Lefler    schedule 11.10.2010    source источник
comment
Хороший вопрос... Я подозреваю, что EventTrigger помечает событие как обработанное, поэтому команда никогда не вызывается. Хотя понятия не имею, как это обойти...   -  person Thomas Levesque    schedule 11.10.2010


Ответы (3)


В итоге я неэлегантно решил свою проблему, добавив файл кода программной части для моего ResourceDictionary, который содержит DataTemplate. Я не знал, что это возможно, но нашел следующее объяснение:

Можно ли установить код за словарем ресурсов в WPF для обработки событий?

Вместо использования EventTrigger для запуска раскадровки, которая скрывает элементы управления редактированием, я добавил обработчик Click в код программной части. Это немного неудобно, так как мне нужно найти панели относительно нажатой кнопки, поскольку это единственная доступная ссылка, но это работает.

Все еще ищу лучшее решение, если у кого-то есть.

person Bill Lefler    schedule 12.10.2010

Я попробовал ваш код, и я обнаружил, что он работает нормально с триггером события на 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;
}

ты точно ничего не пропустил?

person Dean Chalk    schedule 10.12.2010
comment
Может быть, это связано с использованием DataTemplate, как в моем примере кода? - person Bill Lefler; 13.12.2010

Я достиг этого, вызвав команду в триггере события вместе с другим действием, которое вы хотите вызвать:

<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>
person patrickbadley    schedule 08.11.2013