WPF DoubleAnimation CompositionTarget Render

 rotaterAnimation = new DoubleAnimation();
 rotaterAnimation.From = 0;
 rotaterAnimation.To = 360;
 rotaterAnimation.Duration = TimeSpan.FromSeconds(30);
 rotaterAnimation.AutoReverse = false;
 rotaterAnimation.RepeatBehavior = RepeatBehavior.Forever;
 lineRotater.BeginAnimation(RotateTransform.AngleProperty, rotaterAnimation);

 

CompositionTarget.Rendering += CompositionTarget_Rendering;


private void CompositionTarget_Rendering(object? sender, EventArgs e)
{
    if (line == null || rotater == null)
    {
        return;
    }
    AngleStr = Math.Round(rotater.Angle, 2).ToString();
    System.Diagnostics.Debug.WriteLine(AngleStr);
}

 

 

 

 

 

//xaml
<Window x:Class="WpfApp214.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:WpfApp214"
        mc:Ignorable="d"
        WindowState="Maximized"
        Title="{Binding AngleStr,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
        Height="450" Width="800">
    <Grid>
        <Ellipse x:Name="elp"
                 Stroke="Black"
                 StrokeThickness="5"
                 Width="{Binding ElpWidth,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
                 Height="{Binding ElpHeight,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}">
            <Ellipse.RenderTransform>
                <TransformGroup>
                    <RotateTransform x:Name="elpRotater"
                                     CenterX="{Binding ElpCenterX,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
                                     CenterY="{Binding ElpCenterY,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
                </TransformGroup>
            </Ellipse.RenderTransform>
        </Ellipse>
        <Line x:Name="line"
              X1="{Binding LineStartX,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
              Y1="{Binding LineStartY,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
              X2="{Binding LineEndX,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
              Y2="{Binding LineEndY,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
              Stroke="Black"
              StrokeThickness="10"
              StrokeStartLineCap="Round"
              StrokeEndLineCap="Triangle">
            <Line.RenderTransform>
                <RotateTransform x:Name="lineRotater"
                                     CenterX="{Binding ElpCenterX,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
                                     CenterY="{Binding ElpCenterY,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
            </Line.RenderTransform>
        </Line>
    </Grid>
</Window>



//cs
using System.ComponentModel;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApp214
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window, INotifyPropertyChanged
    {

        public MainWindow()
        {
            InitializeComponent();
            var vm = new MainVM(this);
            this.DataContext = vm;
        }

        private void MainWindow_SizeChanged(object sender, SizeChangedEventArgs e)
        {

        }

        private void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {

        }


        private void Init()
        {

        }

        public event PropertyChangedEventHandler? PropertyChanged;
        private void OnPropertyChanged(string propName)
        {
            var handler = PropertyChanged;
            if (handler != null)
            {
                handler?.Invoke(this, new PropertyChangedEventArgs(propName));
            }
        }





    }


    public class MainVM : INotifyPropertyChanged
    {
        Window win;
        private Line line;
        RotateTransform rotater;
        public MainVM(Window winValue)
        {
            win = winValue;
            if (win != null)
            {
                win.Loaded += Win_Loaded;
                win.SizeChanged += Win_SizeChanged;
                win.Closed += Win_Closed;
            }
        }

        private void Win_Closed(object? sender, EventArgs e)
        {
            CompositionTarget.Rendering -= CompositionTarget_Rendering;
        }

        DoubleAnimation rotaterAnimation;
        private void Init()
        {
            var fe = win.Content as FrameworkElement;
            if (fe != null)
            {
                CompositionTarget.Rendering += CompositionTarget_Rendering;
                ElpWidth = fe.ActualHeight;
                ElpHeight = fe.ActualHeight;
                ElpCenterX = fe.ActualWidth / 2;
                ElpCenterY = fe.ActualHeight / 2;
                LineStartX = fe.ActualWidth / 2;
                LineStartY = fe.ActualHeight / 2;
                LineEndX = fe.ActualWidth / 2;
                LineEndY = 10;
                var tempLine = win.FindName("line") as Line;
                if (tempLine != null)
                {
                    line = tempLine;
                    var rotaterTemp = line.RenderTransform as RotateTransform;
                    if (rotaterTemp != null)
                    {
                        rotater = rotaterTemp;
                    }
                }
            }
            if (rotaterAnimation == null)
            {
                var lineRotater = win.FindName("lineRotater") as RotateTransform;
                if (lineRotater != null)
                {
                    rotaterAnimation = new DoubleAnimation();
                    rotaterAnimation.From = 0;
                    rotaterAnimation.To = 360;
                    rotaterAnimation.Duration = TimeSpan.FromSeconds(30);
                    rotaterAnimation.AutoReverse = false;
                    rotaterAnimation.RepeatBehavior = RepeatBehavior.Forever;
                    lineRotater.BeginAnimation(RotateTransform.AngleProperty, rotaterAnimation);
                }
            }
        }

        private void CompositionTarget_Rendering(object? sender, EventArgs e)
        {
            if (line == null || rotater == null)
            {
                return;
            }
            AngleStr = Math.Round(rotater.Angle, 2).ToString();
            System.Diagnostics.Debug.WriteLine(AngleStr);
        }

        private void Win_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            Init();
        }

        private void Win_Loaded(object sender, RoutedEventArgs e)
        {
            Init();
        }

        public event PropertyChangedEventHandler? PropertyChanged;
        private void OnPropertyChanged(string propertyName)
        {
            var handler = PropertyChanged;
            if (handler != null)
            {
                handler?.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        private double elpWidth;
        public double ElpWidth
        {
            get
            {
                return elpWidth;
            }
            set
            {
                if (value != elpWidth)
                {
                    elpWidth = value;
                    OnPropertyChanged(nameof(ElpWidth));
                }
            }
        }

        private double elpHeight;
        public double ElpHeight
        {
            get
            {
                return elpHeight;
            }
            set
            {
                if (value != elpHeight)
                {
                    elpHeight = value;
                    OnPropertyChanged(nameof(ElpHeight));
                }
            }
        }



        private double elpCenterX;
        public double ElpCenterX
        {
            get
            {
                return elpCenterX;
            }
            set
            {
                if (value != elpCenterX)
                {
                    elpCenterX = value;
                    OnPropertyChanged(nameof(ElpCenterX));
                }
            }
        }

        private double elpCenterY;
        public double ElpCenterY
        {
            get
            {
                return elpCenterY;
            }
            set
            {
                if (value != elpCenterY)
                {
                    elpCenterY = value;
                    OnPropertyChanged(nameof(ElpCenterY));
                }
            }
        }

        private double lineStartX;
        public double LineStartX
        {
            get
            {
                return lineStartX;
            }
            set
            {
                if (value != lineStartX)
                {
                    lineStartX = value;
                    OnPropertyChanged(nameof(LineStartX));
                }
            }
        }


        private double lineStartY;
        public double LineStartY
        {
            get
            {
                return lineStartY;
            }
            set
            {
                if (value != lineStartY)
                {
                    lineStartY = value;
                    OnPropertyChanged(nameof(LineStartY));
                }
            }
        }


        private double lineEndX;
        public double LineEndX
        {
            get
            {
                return lineEndX;
            }
            set
            {
                if (value != lineEndX)
                {
                    lineEndX = value;
                    OnPropertyChanged(nameof(LineEndX));
                }
            }
        }

        private double lineEndY;
        public double LineEndY
        {
            get
            {
                return lineEndY;
            }
            set
            {
                if (value != lineEndY)
                {
                    lineEndY = value;
                    OnPropertyChanged(nameof(LineEndY));
                }
            }
        }

        private string angleStr;
        public string AngleStr
        {
            get
            {
                return angleStr;
            }
            set
            {
                if (value != angleStr)
                {
                    angleStr = value;
                    OnPropertyChanged(nameof(AngleStr));
                }
            }
        }
    }
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

posted @ 2025-04-19 16:39  FredGrit  阅读(11)  评论(0)    收藏  举报