【问题标题】:Fire a trigger when Label Content changes标签内容更改时触发触发器
【发布时间】:2018-06-30 17:55:05
【问题描述】:

我刚刚开始学习 WPF,现在我正在使用 C# 和 .NET Framework 4.7 开发我的第二个 WPF 应用程序。

我想在标签的内容发生变化时触发动画。我的视图上有 81 个标签,我想将相同的动画与所有标签相关联。

这是我的标签之一,但所有标签大多相同:

<Label x:Name="c00" Content="{Binding BestIndividual[0]}" Margin="0" BorderThickness="2,2,0,0" BorderBrush="Black" />

搜索,找到了这个solution,但是不知道怎么应用到我需要的。

我想我已经在这篇文章中找到了方法:How to: Trigger an Animation When a Property Value Changes

但是,当标签的内容发生变化时,我可以触发谁?

我发现关于如何触发触发器的唯一方法是当属性具有值时:

<Trigger Property="IsMouseOver" Value="True">

【问题讨论】:

  • 我不认为视图中的 81 个相似标签是一个好主意。要显示集合,请使用 ItemsControl
  • @ASh 谢谢,我刚刚开始学习 WPF。

标签: c# wpf animation


【解决方案1】:

Label 类没有“ContentChanged”事件,但您可以定义自己的自定义 Label 类并覆盖 OnContentChanged 方法:

public class CustomLabel : Label
{
    public event EventHandler ContentChanged;

    protected override void OnContentChanged(object oldContent, object newContent)
    {
        base.OnContentChanged(oldContent, newContent);

        if (ContentChanged != null)
            ContentChanged(this, EventArgs.Empty);
    }
}

在 XAML 中,您将所有 Label 元素替换为您的自定义类型:

<local:CustomLabel x:Name="c00" Content="{Binding BestIndividual[0]}" ContentChanged="OnContentChanged" />

然后您可以在事件处理程序中以编程方式执行动画。

【讨论】:

    【解决方案2】:

    EventTriggers 用于执行动作 - 包括动画 - 以响应 routed event

    正如mm8 建议的那样,Label 控件没有“ContentChanged”事件。但是您可以实现路由事件,而不是使用普通事件:

    public class CustomLabel : Label
    {
        public static readonly RoutedEvent ContentChangedEvent = EventManager.RegisterRoutedEvent(
            "ContentChanged", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(CustomLabel));
    
        public event RoutedEventHandler ContentChanged
        {
            add
            {
                AddHandler(ContentChangedEvent, value);
            }
            remove
            {
                RemoveHandler(ContentChangedEvent, value);
            }
        }
    
        protected override void OnContentChanged(object oldContent, object newContent)
        {
            base.OnContentChanged(oldContent, newContent);
    
            RaiseEvent(new RoutedEventArgs(ContentChangedEvent));
        }
    }
    

    通过这种方式,您可以创建一个带有EventTriggerStyle 来开始动画:

    <Style x:Key="ContentChangedAnimated" TargetType="{x:Type local:CustomLabel}"
            BasedOn="{StaticResource {x:Type Label}}">
        <Style.Triggers>
            <EventTrigger RoutedEvent="ContentChanged">
                <EventTrigger.Actions>
                    <BeginStoryboard>
                        <Storyboard>
                            <DoubleAnimation Duration="0:0:2" Storyboard.TargetProperty="FontSize" 
                                                To="28" AutoReverse="True" />
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger.Actions>
            </EventTrigger>
        </Style.Triggers>
    </Style>
    

    然后您需要将该样式应用于您的(自定义)标签:

    <local:CustomLabel x:Name="c00" Content="{Binding BestIndividual[0]}" Margin="0" Style="{StaticResource ContentChangedAnimated}"
            BorderThickness="2,2,0,0" BorderBrush="Black" />
    

    希望对你有帮助。

    【讨论】:

      猜你喜欢
      • 2021-09-08
      • 2015-08-22
      • 1970-01-01
      • 2016-02-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-08
      • 2022-08-19
      相关资源
      最近更新 更多