WPF Ellipse rotate both in xaml and mvvm in C# include begin,pause and resume
//xaml <Ellipse.Triggers> <EventTrigger RoutedEvent="Ellipse.Loaded"> <BeginStoryboard> <Storyboard> <DoubleAnimation Storyboard.TargetName="elpRotater" Storyboard.TargetProperty="Angle" From="0" To="360" Duration="0:0:10" RepeatBehavior="Forever"/> </Storyboard> </BeginStoryboard> </EventTrigger> </Ellipse.Triggers>
//storyboard begin/pause/resume in mvvm if (storyBoard == null) { storyBoard = new Storyboard(); var doubleAnimation = new DoubleAnimation() { From = 0, To = 360, Duration = TimeSpan.FromSeconds(10), RepeatBehavior = RepeatBehavior.Forever }; storyBoard.Children.Add(doubleAnimation); Storyboard.SetTargetName(doubleAnimation, "elpRotater"); Storyboard.SetTargetProperty(doubleAnimation, new PropertyPath(RotateTransform.AngleProperty)); storyBoard.Begin(elp, true); }
private void OnIsPausedChanged()
{
if(IsPaused)
{
storyBoard.Pause(elp);
}
else
{
storyBoard.Resume(elp);
}
}
//all //xaml <Window x:Class="WpfApp8.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" WindowState="Maximized" xmlns:local="clr-namespace:WpfApp8" mc:Ignorable="d" Title="{Binding AngleStr,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Height="450" Width="800"> <Window.InputBindings> <KeyBinding Key="Space" Command="{Binding SpaceKeyDownCommand}"/> </Window.InputBindings> <Grid> <Ellipse x:Name="elp" HorizontalAlignment="Center" VerticalAlignment="Center" Width="{Binding ElpWidth,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Height="{Binding ElpHeight,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" StrokeThickness="10" RenderTransformOrigin="0.5,0.5"> <!--<Ellipse.Triggers> <EventTrigger RoutedEvent="Ellipse.Loaded"> <BeginStoryboard> <Storyboard> <DoubleAnimation Storyboard.TargetName="elpRotater" Storyboard.TargetProperty="Angle" From="0" To="360" Duration="0:0:10" RepeatBehavior="Forever"/> </Storyboard> </BeginStoryboard> </EventTrigger> </Ellipse.Triggers>--> <Ellipse.RenderTransform> <RotateTransform x:Name="elpRotater" Angle="{Binding ElpAngle,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/> </Ellipse.RenderTransform> <Ellipse.Stroke> <LinearGradientBrush StartPoint="0,0" EndPoint="1.0,1.0"> <GradientStop Color="Black" Offset="0.0"/> <GradientStop Color="Red" Offset="0.1"/> <GradientStop Color="Black" Offset="0.2"/> <GradientStop Color="Red" Offset="0.3"/> <GradientStop Color="Black" Offset="0.4"/> <GradientStop Color="Red" Offset="0.5"/> <GradientStop Color="Black" Offset="0.6"/> <GradientStop Color="Red" Offset="0.7"/> <GradientStop Color="Black" Offset="0.8"/> <GradientStop Color="Red" Offset="0.9"/> <GradientStop Color="Black" Offset="1.0"/> </LinearGradientBrush> </Ellipse.Stroke> <Ellipse.Fill> <ImageBrush ImageSource="{Binding ElpImgSource,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/> </Ellipse.Fill> </Ellipse> </Grid> </Window> //cs using System.ComponentModel; using System.IO; 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; using Console = System.Diagnostics.Debug; namespace WpfApp8 { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); var vm = new MainVM(this); this.DataContext = vm; } } public class MainVM : INotifyPropertyChanged { private Window win; private FrameworkElement fe; private Ellipse elp; private RotateTransform elpRotater; DateTime dtNow = DateTime.Now; int loopCount = 0; private Storyboard storyBoard; public MainVM(Window winValue) { win = winValue; if (win != null) { win.Loaded += Win_Loaded; win.SizeChanged += Win_SizeChanged; } } private void Win_SizeChanged(object sender, SizeChangedEventArgs e) { Init(); } private void Win_Loaded(object sender, RoutedEventArgs e) { Init(); } private void Init() { var tempFe = win.Content as FrameworkElement; if (tempFe != null) { fe = tempFe; ElpHeight = fe.ActualHeight; ElpWidth = fe.ActualHeight; ElpImgSource = GetImgSourceViaUrl(@"../../../Images/1.jpg"); CompositionTarget.Rendering += CompositionTarget_Rendering; } var tempElpRotater = win.FindName("elpRotater") as RotateTransform; if (tempElpRotater != null) { elpRotater = tempElpRotater; } var tempElp = win.FindName("elp") as Ellipse; if (tempElp != null) { elp = tempElp; } if (storyBoard == null) { storyBoard = new Storyboard(); var doubleAnimation = new DoubleAnimation() { From = 0, To = 360, Duration = TimeSpan.FromSeconds(10), RepeatBehavior = RepeatBehavior.Forever }; storyBoard.Children.Add(doubleAnimation); Storyboard.SetTargetName(doubleAnimation, "elpRotater"); Storyboard.SetTargetProperty(doubleAnimation, new PropertyPath(RotateTransform.AngleProperty)); storyBoard.Begin(elp, true); } if (SpaceKeyDownCommand==null) { SpaceKeyDownCommand = new DelCommand(SpaceKeyDownCommandExecuted); } } private void SpaceKeyDownCommandExecuted(object? obj) { IsPaused = !IsPaused; } private void CompositionTarget_Rendering(object? sender, EventArgs e) { if (elpRotater.Angle > 359 && DateTime.Now.Subtract(dtNow) > TimeSpan.FromSeconds(9.9)) { ++loopCount; dtNow = DateTime.Now; } AngleStr = (loopCount * 360 + elpRotater.Angle).ToString(); Console.WriteLine(elpRotater.Angle.ToString()); } private ImageSource GetImgSourceViaUrl(string imgUrl) { if (!File.Exists(imgUrl)) { return null; } BitmapImage bmi = new BitmapImage(); bmi.BeginInit(); bmi.UriSource = new Uri(imgUrl, UriKind.RelativeOrAbsolute); bmi.EndInit(); if (bmi.CanFreeze) { bmi.Freeze(); } return bmi; } public DelCommand SpaceKeyDownCommand { get; set; } public event PropertyChangedEventHandler? PropertyChanged; public void OnPropertyChanged(string propertyName) { var handler = PropertyChanged; if (handler != null) { handler?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } private bool isPaused; public bool IsPaused { get { return isPaused; } set { if(value!=isPaused) { isPaused = value; OnPropertyChanged(nameof(IsPaused)); OnIsPausedChanged(); } } } private void OnIsPausedChanged() { if(IsPaused) { storyBoard.Pause(elp); } else { storyBoard.Resume(elp); } } private string angleStr; public string AngleStr { get { return angleStr; } set { if (angleStr != value) { angleStr = value; OnPropertyChanged(nameof(AngleStr)); } } } private ImageSource elpImgSource; public ImageSource ElpImgSource { get { return elpImgSource; } set { if (value != elpImgSource) { elpImgSource = value; OnPropertyChanged(nameof(ElpImgSource)); } } } private double elpWidth; public double ElpWidth { get { return elpWidth; } set { if (value != elpWidth) { elpWidth = value; OnPropertyChanged(nameof(ElpWidth)); } } } public double elpHeight; public double ElpHeight { get { return elpHeight; } set { if (value != elpHeight) { elpHeight = value; OnPropertyChanged(nameof(ElpHeight)); } } } public double elpAngle; public double ElpAngle { get { return elpAngle; } set { if (value != elpAngle) { elpAngle = value; OnPropertyChanged(nameof(ElpAngle)); } } } } public class DelCommand : ICommand { private Action<object?> execute; private Predicate<object?> canExecute; public DelCommand(Action<object?> executeValue, Predicate<object?> canExecuteValue = null) { execute = executeValue; canExecute = canExecuteValue; } public event EventHandler? CanExecuteChanged { add { CommandManager.RequerySuggested += value; } remove { CommandManager.RequerySuggested -= value; } } public bool CanExecute(object? parameter) { if (canExecute == null) { return true; } return canExecute(parameter); } public void Execute(object? parameter) { execute(parameter); } } }




浙公网安备 33010602011771号