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

发布于 2024-09-26 16:03:41 字数 707 浏览 8 评论 0原文

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

如果我拾取 PreviewMouseDown 事件,Storyboard 工作正常,但该命令永远不会被调用。如果我在 EventTrigger 中拾取 MouseDown 事件,则命令将起作用,但 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>

I have a Button in a DataTemplate that is bound to a Command in my ViewModel. The button also has an EventTrigger that kicks off a Storyboard that hides the edit controls (of which the button is a part.)

The Storyboard works fine if I pick up the PreviewMouseDown event, but the Command never gets called. If I pick up the MouseDown event in my EventTrigger, the Command works, but the Storyboard doesn't execute.

How can I get both the Command and the Storyboard to execute when the button is clicked?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

橘味果▽酱 2024-10-03 16:03:41

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

Is it possible to set code Behind a Resource Dictionary in WPF for event Handling?< /a>

我没有使用 EventTrigger 来开始隐藏编辑控件的 Storyboard,而是向代码隐藏添加了 Click 处理程序。这有点混乱,因为我必须相对于单击的按钮定位面板,因为这是唯一可用的参考,但它有效。

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

I ended up inelegantly solving my problem by adding a code-behind file for my ResourceDictionary that contains the DataTemplate. I wasn't aware that this was possible, but found this explanation:

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

Instead of using the EventTrigger to begin a Storyboard that hides the edit controls I added a Click handler to the code-behind. It's a bit kludgy as I have to locate the panels relative to the button clicked as that is the only reference available, but it works.

Still looking for a better solution if anyone has one.

胡大本事 2024-10-03 16:03:41

我试过你的代码,我发现它与 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;
}

您确定没有错过什么吗?

Ive tried your code, and I find that it works OK with the event trigger on PreviewMouseDown, its just that the command is executed first, then the animation fires.

Heres my resources

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

my 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>

and my view model

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;
}

are you sure you havent missed something ?

柳絮泡泡 2024-10-03 16:03:41

我通过调用 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>

I achieved this by invoking the command within the eventtrigger along with the other action you want to trigger:

<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>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文