WPF rotate Circle via MouseDown,MouseMove,MouseUp in mvvm


//
xaml <Window x:Class="WpfApp57.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:behavior="http://schemas.microsoft.com/xaml/behaviors" WindowState="Maximized" xmlns:local="clr-namespace:WpfApp57" mc:Ignorable="d" Title="{Binding RotatedStr,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Height="450" Width="800"> <behavior:Interaction.Triggers> <behavior:EventTrigger EventName="MouseDown"> <behavior:InvokeCommandAction Command="{Binding MouseDownCommand}"/> </behavior:EventTrigger> <behavior:EventTrigger EventName="MouseMove"> <behavior:InvokeCommandAction Command="{Binding MouseMoveCommand}"/> </behavior:EventTrigger> <behavior:EventTrigger EventName="MouseUp"> <behavior:InvokeCommandAction Command="{Binding MouseUpCommand}"/> </behavior:EventTrigger> </behavior:Interaction.Triggers> <Grid> <Ellipse x:Name="elp" Width="{Binding ElpWidth}" Height="{Binding ElpHeight}" RenderTransformOrigin="0.5,0.5"> <Ellipse.Fill> <!--<LinearGradientBrush StartPoint="0,0" EndPoint="0,1"> <GradientStop Color="Orange" Offset="0"/> <GradientStop Color="Orange" Offset="0.2"/> <GradientStop Color="Yellow" Offset="0.2"/> <GradientStop Color="Yellow" Offset="0.4"/> <GradientStop Color="Green" Offset="0.4"/> <GradientStop Color="Green" Offset="0.495"/> <GradientStop Color="Red" Offset="0.495"/> <GradientStop Color="Red" Offset="0.505"/> <GradientStop Color="Green" Offset="0.505"/> <GradientStop Color="Green" Offset="0.6"/> <GradientStop Color="Blue" Offset="0.6"/> <GradientStop Color="Blue" Offset="0.8"/> <GradientStop Color="Cyan" Offset="0.8"/> <GradientStop Color="Cyan" Offset="1.0"/> </LinearGradientBrush>--> <ImageBrush ImageSource="{Binding ElpImgSource}"/> </Ellipse.Fill> <Ellipse.RenderTransform> <TransformGroup> <RotateTransform x:Name="rotateTransform"/> </TransformGroup> </Ellipse.RenderTransform> </Ellipse> </Grid> </Window> //cs using System.ComponentModel; using System.Reflection; using System.Runtime.CompilerServices; using System.Security.AccessControl; 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.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace WpfApp57 { /// <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 Ellipse elp; private RotateTransform rotater; private Point prevPt; private Point originPt; public MainVM(Window winValue) { win=winValue; if (win!=null) { win.Loaded+=Win_Loaded; } } private void Win_Loaded(object sender, RoutedEventArgs e) { var tempElp = win.FindName("elp") as Ellipse; if (tempElp!=null) { elp=tempElp; if (elp!=null) { var tempRotater = elp.FindName("rotateTransform") as RotateTransform; if (tempRotater!=null) { rotater = tempRotater; } } } ElpWidth=win.ActualHeight-50; ElpHeight=win.ActualHeight-50; originPt=new Point(win.ActualWidth/2, win.ActualHeight/2); var executeAssembly=Assembly.GetExecutingAssembly(); using (var stream = executeAssembly.GetManifestResourceStream("WpfApp57.Images.1.jpg")) { BitmapImage bmi = new BitmapImage(); bmi.BeginInit(); bmi.StreamSource= stream; bmi.EndInit(); if(bmi.CanFreeze) { bmi.Freeze(); } ElpImgSource=bmi; } } private DelCommand mouseDownCommand; public DelCommand MouseDownCommand { get { if (mouseDownCommand==null) { mouseDownCommand=new DelCommand(MouseDownCommandExecuted); } return mouseDownCommand; } } private void MouseDownCommandExecuted(object? obj) { if (Mouse.LeftButton==MouseButtonState.Pressed) { prevPt=Mouse.GetPosition(win); elp.CaptureMouse(); } } private ICommand mouseMoveCommand; public ICommand MouseMoveCommand { get { if (mouseMoveCommand==null) { mouseMoveCommand=new DelCommand(MouseMoveCommandExecuted); } return mouseMoveCommand; } } private void MouseMoveCommandExecuted(object? obj) { if (Mouse.LeftButton==MouseButtonState.Pressed) { Vector prevVec = Point.Subtract(prevPt, originPt); Point newPt = Mouse.GetPosition(win); Vector newVec = Point.Subtract(newPt, originPt); double rotatedAngle = Vector.AngleBetween(prevVec, newVec); rotater.Angle+=rotatedAngle; prevPt=newPt; RotatedStr=rotater.Angle.ToString(); } } private ICommand mouseUpCommand; public ICommand MouseUpCommand { get { if (mouseUpCommand==null) { mouseUpCommand=new DelCommand(MouseUpCommandExecuted); } return mouseUpCommand; } } private void MouseUpCommandExecuted(object? obj) { if (Mouse.LeftButton!=MouseButtonState.Released) { elp.ReleaseMouseCapture(); } } public event PropertyChangedEventHandler? PropertyChanged; private void OnPropertyChanged([CallerMemberName] 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(); } } } private double elpHeight; public double ElpHeight { get { return elpHeight; } set { if (value!=elpHeight) { elpHeight=value; OnPropertyChanged(); } } } private string rotatedStr; public string RotatedStr { get { return rotatedStr; } set { if (value!=rotatedStr) { rotatedStr=value; OnPropertyChanged(); } } } private ImageSource elpImgSource; public ImageSource ElpImgSource { get { return elpImgSource; } set { if (value!=elpImgSource) { elpImgSource=value; OnPropertyChanged(); } } } } 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) { return canExecute==null ? true : canExecute(parameter); } public void Execute(object? parameter) { execute(parameter); } } }

 

 

 

image

 

 

 

image

 

 

 

image

 

 

 

image

 

posted @ 2025-08-25 16:47  FredGrit  阅读(7)  评论(0)    收藏  举报