Я пытаюсь создать прямоугольник выделения с возможностью изменять его положение и размер, а также вращать его — все будет делаться перетаскиванием мыши.
Мне удалось переместить объект, но у меня возникла проблема с поворотом и изменением размера.
Изменение размера работает нормально до поворота, но после поворота прямоугольник меняет положение при изменении размера.
При вращении в первый раз все вроде бы работает нормально, но во второй раз прямоугольник подпрыгивает и меняет положение.
Прилагается изображение и написанный мной код.
Как заставить RotateThumb и CenterBottomThumb работать правильно?

cs:
с использованием System.ComponentModel; используя System.Linq; использование System.Windows; использование System.Windows.Controls.Primitives; используя System.Windows.Input; использование System.Windows.Media; использование Linq; пространство имен SelectionRect { общедоступный частичный класс MainWindow: Окно { частный двойной _initialLeft; частный двойной _initialTop; общедоступное главное окно() { ИнициализироватьКомпонент(); DataContext = new RectModel () {Высота = 200, Ширина = 100, Слева = 20, Сверху = 50}; } Private void CenterBottomThumb_DragDelta (отправитель объекта, System.Windows.Controls.Primitives.DragDeltaEventArgs e) { вар большой палец = отправитель как большой палец; вар модель = палец.DataContext как RectModel; if (model.Height + e.VerticalChange >= 1) { model.Height += e.VerticalChange; } } частная пустота CenterTopThumb_DragDelta (отправитель объекта, System.Windows.Controls.Primitives.DragDeltaEventArgs e) { } Private void RotateThumb_DragDelta (отправитель объекта, System.Windows.Controls.Primitives.DragDeltaEventArgs e) { вар большой палец = отправитель как большой палец; вар модель = палец.DataContext как RectModel; вар начальныйАнгл = модель.Угол; вар центр = новая точка (model.CenterX, model.CenterY); центр = RectGrid.TranslatePoint(центр, Canvas1); вар currentPos = Mouse.GetPosition(Canvas1); model.Angle = center.GetAngle(currentPos) + 90; var Rect = новый Rect(_initialLeft, _initialTop, model.Width, model.Height); вар angularPoints = new [] { Rect.TopLeft, Rect.TopRight, Rect.BottomRight, Rect.BottomLeft }; вар м = новая матрица (); m.RotateAt(модель.Угол, центр.X, центр.Y); m.Transform(cornerPoints); model.Left = angularPoints.Min(p => p.X); model.Top = angularPoints.Min(p => p.Y); } Private void RotateThumb_DragStarted (отправитель объекта, System.Windows.Controls.Primitives.DragStartedEventArgs e) { вар большой палец = отправитель как большой палец; вар модель = палец.DataContext как RectModel; _initialLeft = модель.Лефт; _initialTop = модель.Верх; } Private void CenterLeftThumb_DragDelta (отправитель объекта, System.Windows.Controls.Primitives.DragDeltaEventArgs e) { } частная пустота CenterRightThumb_DragDelta (отправитель объекта, System.Windows.Controls.Primitives.DragDeltaEventArgs e) { } частная пустота CenterThumb_DragDelta (отправитель объекта, System.Windows.Controls.Primitives.DragDeltaEventArgs e) { вар большой палец = отправитель как большой палец; вар модель = палец.DataContext как RectModel; model.Top += e.VerticalChange; model.Left += e.HorizontalChange; } частная пустота CenterThumbBorder_MouseDown (отправитель объекта, MouseButtonEventArgs e) { } Private void LeftBottomThumb_DragDelta (отправитель объекта, System.Windows.Controls.Primitives.DragDeltaEventArgs e) { } Private void LeftTopThumb_DragDelta (отправитель объекта, System.Windows.Controls.Primitives.DragDeltaEventArgs e) { } Private void RightTopThumb_DragDelta (отправитель объекта, System.Windows.Controls.Primitives.DragDeltaEventArgs e) { } Private void RightBottomThumb_DragDelta (отправитель объекта, System.Windows.Controls.Primitives.DragDeltaEventArgs e) { } } общедоступный статический класс Ex { public static double GetAngle(это System.Windows.Point p1, System.Windows.Point p2) { вар xDiff = p2.X - p1.X; вар yDiff = p2.Y - p1.Y; return Math.Atan2(yDiff, xDiff) * 180.0/Math.PI; } } класс RectModel: INotifyPropertyChanged { частный двойной _Angle; общественный двойной угол { получить {вернуться _Angle; } набор { if (значение == _Angle) return; _Угол = значение; OnPropertyChanged(имя(Угол)); } } частный двойной _Height; общественная двойная высота { получить {вернуться _Height; } набор { if (значение == _Height) return; _Высота = значение; OnPropertyChanged(имя(Высота)); } } частная двойная _Width; общественный двойной ширины { получить {возврат _Width; } набор { если (значение == _Width) return; _Ширина = значение; OnPropertyChanged(имя(Ширина)); } } частный двойной _Top; публичный двойной топ { получить {вернуться _Top; } набор { если (значение == _Top) return; _Top = значение; OnPropertyChanged(nameof(Top)); } } частный двойной _Left; общественный двойной левый { получить {вернуться _Left; } набор { если (значение == _Left) return; _Left = значение; OnPropertyChanged(имя(слева)); } } общественный двойной CenterX => Ширина / 2; общедоступный двойной CenterY => Высота/2; публичное событие PropertyChangedEventHandler PropertyChanged; частная пустота OnPropertyChanged (строковое имя свойства) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } }
Мобильная версия