NoteMAUI/ResizableCanvasPage.xaml.cs
2024-11-11 18:07:11 +03:00

141 lines
5.6 KiB
C#

using Microsoft.Maui.Controls;
using Microsoft.Maui.Graphics;
using System;
namespace NotesDataAnalyst
{
public partial class ResizableCanvasPage : ContentPage
{
private const double InitialWidth = 150;
private const double InitialHeight = 100;
private double startX, startY;
public ResizableCanvasPage()
{
InitializeComponent();
}
private void AddResizableObject(double x, double y)
{
// Ñîçäàåì îñíîâíîé êîíòåéíåð (Frame) äëÿ îáúåêòà è ðó÷êè
var resizableFrame = new Frame
{
BackgroundColor = Colors.LightBlue,
BorderColor = Colors.DarkBlue,
CornerRadius = 8,
WidthRequest = InitialWidth,
HeightRequest = InitialHeight,
Padding = 0, // Óáèðàåì âíóòðåííèå îòñòóïû
Content = new Grid() // Èñïîëüçóåì Grid äëÿ äîáàâëåíèÿ ñîäåðæèìîãî è ðó÷êè
};
// Ñîçäàåì ñîäåðæèìîå âíóòðè ôðåéìà
var content = new StackLayout
{
BackgroundColor = Colors.LightBlue,
Children =
{
new Label { Text = "Resizable Object", HorizontalOptions = LayoutOptions.Center, VerticalOptions = LayoutOptions.Center }
}
};
var resizeHandle = new BoxView
{
BackgroundColor = Colors.Gray,
WidthRequest = 20,
HeightRequest = 20
};
// Ñîçäàåì Grid âíóòðè Frame
var grid = (Grid)resizableFrame.Content;
// Íàñòðîèì ñåòêó: äîáàâèì äâà ñòîëáöà è äâå ñòðîêè
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Star });
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto }); // äëÿ ðó÷êè
grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Star });
grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto }); // äëÿ ðó÷êè
// Äîáàâëÿåì ñîäåðæèìîå â ïåðâóþ ÿ÷åéêó (ñòîëáåö 0, ñòðîêà 0)
grid.Children.Add(content); // Áåç óêàçàíèÿ êîëîíîê/ñòðîê
// Äîáàâëÿåì ðó÷êó â ïðàâûé íèæíèé óãîë (ñòîëáåö 1, ñòðîêà 1)
grid.Children.Add(resizeHandle); // Áåç óêàçàíèÿ êîëîíîê/ñòðîê
// Óñòàíàâëèâàåì ñòðîêó è êîëîíêó äëÿ ðó÷êè
Grid.SetRow(resizeHandle, 1);
Grid.SetColumn(resizeHandle, 1);
// Äîáàâëÿåì ïàíîðàìó äëÿ ïåðåìåùåíèÿ îáúåêòà
var panGesture = new PanGestureRecognizer();
panGesture.PanUpdated += (s, e) => OnDragPanUpdated(s, e, resizableFrame);
resizableFrame.GestureRecognizers.Add(panGesture);
// Äîáàâëÿåì ïàíîðàìó äëÿ èçìåíåíèÿ ðàçìåðà
var resizePanGesture = new PanGestureRecognizer();
resizePanGesture.PanUpdated += (s, e) => OnResizePanUpdated(s, e, resizableFrame, resizeHandle);
resizeHandle.GestureRecognizers.Add(resizePanGesture);
// Óñòàíàâëèâàåì ïîçèöèþ ôðåéìà
AbsoluteLayout.SetLayoutBounds(resizableFrame, new Rect(x, y, InitialWidth, InitialHeight));
CanvasLayout.Children.Add(resizableFrame);
// Îáíîâëÿåì ïîçèöèþ ðó÷êè
UpdateResizeHandlePosition(resizableFrame, resizeHandle);
}
private void OnDragPanUpdated(object sender, PanUpdatedEventArgs e, Frame frame)
{
if (e.StatusType == GestureStatus.Started)
{
startX = AbsoluteLayout.GetLayoutBounds(frame).X;
startY = AbsoluteLayout.GetLayoutBounds(frame).Y;
}
else if (e.StatusType == GestureStatus.Running)
{
double x = startX + e.TotalX;
double y = startY + e.TotalY;
AbsoluteLayout.SetLayoutBounds(frame, new Rect(x, y, frame.WidthRequest, frame.HeightRequest));
// Îáíîâëÿåì ïîçèöèþ ðó÷êè
var resizeHandle = (BoxView)((Grid)frame.Content).Children[1];
UpdateResizeHandlePosition(frame, resizeHandle);
}
}
private void OnResizePanUpdated(object sender, PanUpdatedEventArgs e, Frame frame, BoxView resizeHandle)
{
if (e.StatusType == GestureStatus.Started)
{
startX = frame.WidthRequest;
startY = frame.HeightRequest;
}
else if (e.StatusType == GestureStatus.Running)
{
double newWidth = Math.Max(50, startX + e.TotalX);
double newHeight = Math.Max(50, startY + e.TotalY);
frame.WidthRequest = newWidth;
frame.HeightRequest = newHeight;
// Îáíîâëÿåì ïîçèöèþ ðó÷êè ïîñëå èçìåíåíèÿ ðàçìåðîâ
UpdateResizeHandlePosition(frame, resizeHandle);
}
}
private void UpdateResizeHandlePosition(Frame frame, BoxView resizeHandle)
{
var frameBounds = AbsoluteLayout.GetLayoutBounds(frame);
double x = frameBounds.X + frame.WidthRequest - resizeHandle.WidthRequest;
double y = frameBounds.Y + frame.HeightRequest - resizeHandle.HeightRequest;
AbsoluteLayout.SetLayoutBounds(resizeHandle, new Rect(x, y, resizeHandle.WidthRequest, resizeHandle.HeightRequest));
}
protected override void OnAppearing()
{
base.OnAppearing();
AddResizableObject(100, 100);
AddResizableObject(400, 200);
AddResizableObject(700, 400);
}
}
}