【问题标题】:EventTrigger and DataTrigger not working togetherEventTrigger 和 DataTrigger 不能一起工作
【发布时间】:2021-08-07 10:20:59
【问题描述】:

我有一个要在ItemsControl 中显示的项目集合。 当一个项目是新的时,它应该淡入,当它的StateType 属性更改为“Finished”时它应该淡出。

我的ItemsControlItemTemplateDockPanel

<DockPanel.Style>
    <Style TargetType="{x:Type DockPanel}">
        <Style.Triggers>
            <!-- Fades in as expected but DataTrigger below never fades out -->
            <EventTrigger RoutedEvent="Loaded">
                <BeginStoryboard>
                    <Storyboard>
                        <DoubleAnimation Storyboard.TargetProperty="Opacity" Duration="0:0:1" From="0" To="1"/>
                    </Storyboard>
                </BeginStoryboard>
            </EventTrigger>

    <!-- Using this for fading in everything works fine (first StateType of a new item is Running) -->
    <!--
    <DataTrigger Binding="{Binding StateType}" Value="{x:Static local:AppStateItem+Type.Running}">
        <DataTrigger.EnterActions>
            <BeginStoryboard>
                <Storyboard>
                    <DoubleAnimation Storyboard.TargetProperty="Opacity" Duration="0:0:1" From="0" To="1"/>
                </Storyboard>
            </BeginStoryboard>
        </DataTrigger.EnterActions>
    </DataTrigger>
    -->
            <!-- fade out trigger -->
            <DataTrigger Binding="{Binding StateType}" Value="{x:Static local:AppStateItem+Type.Finished}">
                <DataTrigger.EnterActions>
                    <BeginStoryboard>
                        <Storyboard>
                            <DoubleAnimation Storyboard.TargetProperty="Opacity" Duration="0:0:1" From="1" To="0" BeginTime="0:0:4"/>
                        </Storyboard>
                    </BeginStoryboard>
                </DataTrigger.EnterActions>
            </DataTrigger>
        </Style.Triggers>
    </Style>
</DockPanel.Style>

问题是:它淡入但从不淡出。如果我用注释过的DataTrigger 替换EventTrigger 以使其淡入淡出,它会按预期工作。 EventTrigger 是否会覆盖某些东西,即使它应该只触发一次?

【问题讨论】:

    标签: c# wpf storyboard datatrigger eventtrigger


    【解决方案1】:

    您的示例适用于两个 DataTriggers

    确保实现INotifyPropertyChanged 并为StateType 属性引发PropertyChanged 事件。

    您可能还想从第二个Storyboard 中删除BeginTime 设置。

    试试这个最小的可重现样本:

    MainWindow.xaml:

    <Window x:Class="WpfApp1.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:WpfApp1"
            mc:Ignorable="d"
            Title="MainWindow" Height="450" Width="800">
        <DockPanel>
            <DockPanel.Style>
                <Style TargetType="{x:Type DockPanel}">
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding StateType}" Value="{x:Static local:AppStateItem.Running}">
                            <DataTrigger.EnterActions>
                                <BeginStoryboard>
                                    <Storyboard >
                                        <DoubleAnimation Storyboard.TargetProperty="Opacity" Duration="0:0:1" From="0" To="1"/>
                                    </Storyboard>
                                </BeginStoryboard>
                            </DataTrigger.EnterActions>
                        </DataTrigger>
                        <!-- fade out trigger -->
                        <DataTrigger Binding="{Binding StateType}" Value="{x:Static local:AppStateItem.Finished}">
                            <DataTrigger.EnterActions>
                                <BeginStoryboard>
                                    <Storyboard>
                                        <DoubleAnimation Storyboard.TargetProperty="Opacity" Duration="0:0:1" From="1" To="0" />
                                    </Storyboard>
                                </BeginStoryboard>
                            </DataTrigger.EnterActions>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </DockPanel.Style>
            <Button Content="Fade out" Click="Button_Click" DockPanel.Dock="Bottom" />
            <TextBlock FontSize="14" FontWeight="Bold" Text="test" />
        </DockPanel>
    </Window>
    

    MainWindow.xaml.cs:

    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        public MainWindow()
        {
            InitializeComponent();
            DataContext = this;
        }
    
        private AppStateItem _stateType;
        public AppStateItem StateType
        {
            get { return _stateType; }
            set { _stateType = value; NotifyPropertyChanged(); }
        }
    
        public event PropertyChangedEventHandler PropertyChanged; 
        private void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            StateType = AppStateItem.Finished;
        }
    }
    
    public enum AppStateItem
    {
        Running,
        Finished
    }
    

    【讨论】:

    • 是的,这两个 DataTrigger 可以工作。但是 EventTrigger/DataTrigger 组合对我不起作用。我原本想淡入“加载”
    • 为什么不使用两个数据触发器?
    • 目前我正在使用它们。但这有点解决方法。我不希望它依赖于起始状态。例如,我也有“等待”。第二个问题是:当淡入完全完成之前状态发生变化时,它会停止。我通过在淡出触发器处将快速动画设置为不透明度 1 来解决此问题。这些动画对我来说有点反复试验。
    • 听起来您应该以编程方式创建动画,而不是依赖 XAML 构造。
    猜你喜欢
    • 2012-07-11
    • 1970-01-01
    • 2010-12-13
    • 2016-03-19
    • 2014-01-07
    • 2019-08-17
    • 2016-11-23
    • 2019-02-18
    • 2015-05-16
    相关资源
    最近更新 更多