You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WPF如何基于自定义事件触发属性动画?

解决方案:用定时器触发Border背景色动画

WPF中定时器的Elapsed事件属于后台线程触发,不需要在XAML中关联该事件,直接在后台代码中绑定事件处理逻辑即可,核心是要通过Dispatcher切换到UI线程操作控件。以下是具体实现步骤:

1. XAML部分(保留动画定义或直接后台创建)

如果想复用原有动画逻辑,可在XAML中定义Storyboard:

<Window x:Class="WpfColorTimer.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <!-- 要动画的Border,设置Name方便后台调用 -->
        <Border x:Name="TargetBorder" Width="200" Height="200" Background="LightBlue">
            <Border.Resources>
                <!-- 定义背景色切换动画 -->
                <Storyboard x:Key="BgColorStoryboard">
                    <ColorAnimation 
                        Storyboard.TargetName="TargetBorder"
                        Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)"
                        From="LightBlue" To="LightGreen" Duration="0:0:0.5"
                        AutoReverse="True" RepeatBehavior="1x"/>
                </Storyboard>
            </Border.Resources>
        </Border>
    </Grid>
</Window>

2. 后台C#代码(定时器绑定与UI线程调度)

在窗口后台代码中初始化定时器,绑定Elapsed事件,并通过Dispatcher.Invoke确保UI操作在主线程执行:

using System;
using System.Timers;
using System.Windows;
using System.Windows.Media.Animation;

namespace WpfColorTimer
{
    public partial class MainWindow : Window
    {
        private Timer _bgTimer;

        public MainWindow()
        {
            InitializeComponent();
            SetupTimer();
        }

        private void SetupTimer()
        {
            // 初始化1秒间隔的定时器
            _bgTimer = new Timer(1000);
            _bgTimer.Elapsed += OnBgTimerElapsed;
            _bgTimer.Start();
        }

        private void OnBgTimerElapsed(object sender, ElapsedEventArgs e)
        {
            // 定时器在后台线程,必须通过Dispatcher切换到UI线程
            Dispatcher.Invoke(() =>
            {
                // 调用XAML中定义的Storyboard
                var storyboard = (Storyboard)TargetBorder.Resources["BgColorStoryboard"];
                storyboard.Begin();
            });
        }

        // 窗口关闭时释放定时器,避免内存泄漏
        protected override void OnClosed(EventArgs e)
        {
            base.OnClosed(e);
            _bgTimer?.Stop();
            _bgTimer?.Dispose();
        }
    }
}

简化方案:直接后台创建动画

如果不需要复用XAML中的动画,也可以直接在后台代码创建动画并应用:

private void OnBgTimerElapsed(object sender, ElapsedEventArgs e)
{
    Dispatcher.Invoke(() =>
    {
        var colorAnim = new ColorAnimation
        {
            From = Colors.LightBlue,
            To = Colors.LightGreen,
            Duration = TimeSpan.FromSeconds(0.5),
            AutoReverse = true
        };
        // 直接将动画应用到Border的背景色属性
        ((SolidColorBrush)TargetBorder.Background).BeginAnimation(SolidColorBrush.ColorProperty, colorAnim);
    });
}

关键注意点

  • 定时器的Elapsed事件运行在非UI线程,必须使用Dispatcher.Invoke/Dispatcher.BeginInvoke切换到UI线程,否则会触发跨线程操作UI的异常。
  • 窗口关闭时务必停止并释放定时器,防止内存泄漏。

内容的提问来源于stack exchange,提问作者Curtwagner1984

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 08:12:13