т
This commit is contained in:
parent
5dbd13040f
commit
c3fc868156
2 changed files with 61 additions and 55 deletions
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
<!-- Главная страница приложения -->
|
<!-- Главная страница приложения -->
|
||||||
<FlyoutItem Title="Главная" Icon="add.png">
|
<FlyoutItem Title="Главная" Icon="add.png">
|
||||||
<ShellContent ContentTemplate="{DataTemplate local:GraphPage}" />
|
<ShellContent ContentTemplate="{DataTemplate local:ResizableCanvasPage}" />
|
||||||
</FlyoutItem>
|
</FlyoutItem>
|
||||||
|
|
||||||
<!-- Выпадающий список категорий -->
|
<!-- Выпадающий список категорий -->
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
using Microsoft.Maui.Controls;
|
using Microsoft.Maui.Controls;
|
||||||
using Microsoft.Maui.Graphics;
|
using Microsoft.Maui.Graphics;
|
||||||
using Microsoft.Maui.Layouts;
|
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace NotesDataAnalyst
|
namespace NotesDataAnalyst
|
||||||
|
|
@ -10,7 +9,6 @@ namespace NotesDataAnalyst
|
||||||
private const double InitialWidth = 150;
|
private const double InitialWidth = 150;
|
||||||
private const double InitialHeight = 100;
|
private const double InitialHeight = 100;
|
||||||
private double startX, startY;
|
private double startX, startY;
|
||||||
private bool isResizing;
|
|
||||||
|
|
||||||
public ResizableCanvasPage()
|
public ResizableCanvasPage()
|
||||||
{
|
{
|
||||||
|
|
@ -27,103 +25,111 @@ namespace NotesDataAnalyst
|
||||||
CornerRadius = 8,
|
CornerRadius = 8,
|
||||||
WidthRequest = InitialWidth,
|
WidthRequest = InitialWidth,
|
||||||
HeightRequest = InitialHeight,
|
HeightRequest = InitialHeight,
|
||||||
Padding = 0,
|
Padding = 0, // Óáèðàåì âíóòðåííèå îòñòóïû
|
||||||
HasShadow = true
|
Content = new Grid() // Èñïîëüçóåì Grid äëÿ äîáàâëåíèÿ ñîäåðæèìîãî è ðó÷êè
|
||||||
};
|
};
|
||||||
|
|
||||||
var content = new Label
|
// Ñîçäàåì ñîäåðæèìîå âíóòðè ôðåéìà
|
||||||
|
var content = new StackLayout
|
||||||
{
|
{
|
||||||
Text = "Resizable Object",
|
BackgroundColor = Colors.LightBlue,
|
||||||
HorizontalOptions = LayoutOptions.Center,
|
Children =
|
||||||
VerticalOptions = LayoutOptions.Center
|
{
|
||||||
|
new Label { Text = "Resizable Object", HorizontalOptions = LayoutOptions.Center, VerticalOptions = LayoutOptions.Center }
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
resizableFrame.Content = content;
|
|
||||||
|
|
||||||
// Ñîçäàåì ðó÷êó äëÿ èçìåíåíèÿ ðàçìåðà
|
|
||||||
var resizeHandle = new BoxView
|
var resizeHandle = new BoxView
|
||||||
{
|
{
|
||||||
BackgroundColor = Colors.Gray,
|
BackgroundColor = Colors.Gray,
|
||||||
WidthRequest = 20,
|
WidthRequest = 20,
|
||||||
HeightRequest = 20,
|
HeightRequest = 20
|
||||||
HorizontalOptions = LayoutOptions.End,
|
|
||||||
VerticalOptions = LayoutOptions.End
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Ñîçäàåì ñëîé AbsoluteLayout äëÿ ðó÷êè è ôðåéìà
|
// Ñîçäàåì Grid âíóòðè Frame
|
||||||
var layout = new AbsoluteLayout();
|
var grid = (Grid)resizableFrame.Content;
|
||||||
AbsoluteLayout.SetLayoutBounds(resizableFrame, new Rect(0, 0, InitialWidth, InitialHeight));
|
|
||||||
layout.Children.Add(resizableFrame);
|
|
||||||
|
|
||||||
// Ïîçèöèîíèðóåì ðó÷êó
|
// Íàñòðîèì ñåòêó: äîáàâèì äâà ñòîëáöà è äâå ñòðîêè
|
||||||
AbsoluteLayout.SetLayoutFlags(resizeHandle, AbsoluteLayoutFlags.PositionProportional);
|
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Star });
|
||||||
AbsoluteLayout.SetLayoutBounds(resizeHandle, new Rect(1, 1, 20, 20));
|
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto }); // äëÿ ðó÷êè
|
||||||
layout.Children.Add(resizeHandle);
|
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();
|
var panGesture = new PanGestureRecognizer();
|
||||||
panGesture.PanUpdated += (s, e) => OnDragPanUpdated(s, e, layout);
|
panGesture.PanUpdated += (s, e) => OnDragPanUpdated(s, e, resizableFrame);
|
||||||
resizableFrame.GestureRecognizers.Add(panGesture);
|
resizableFrame.GestureRecognizers.Add(panGesture);
|
||||||
|
|
||||||
// Äîáàâëÿåì îáðàáîò÷èê äëÿ èçìåíåíèÿ ðàçìåðà
|
// Äîáàâëÿåì ïàíîðàìó äëÿ èçìåíåíèÿ ðàçìåðà
|
||||||
var resizePanGesture = new PanGestureRecognizer();
|
var resizePanGesture = new PanGestureRecognizer();
|
||||||
resizePanGesture.PanUpdated += (s, e) => OnResizePanUpdated(s, e, layout);
|
resizePanGesture.PanUpdated += (s, e) => OnResizePanUpdated(s, e, resizableFrame, resizeHandle);
|
||||||
resizeHandle.GestureRecognizers.Add(resizePanGesture);
|
resizeHandle.GestureRecognizers.Add(resizePanGesture);
|
||||||
|
|
||||||
// Óñòàíàâëèâàåì íà÷àëüíóþ ïîçèöèþ
|
// Óñòàíàâëèâàåì ïîçèöèþ ôðåéìà
|
||||||
AbsoluteLayout.SetLayoutBounds(layout, new Rect(x, y, InitialWidth, InitialHeight));
|
AbsoluteLayout.SetLayoutBounds(resizableFrame, new Rect(x, y, InitialWidth, InitialHeight));
|
||||||
CanvasLayout.Children.Add(layout);
|
CanvasLayout.Children.Add(resizableFrame);
|
||||||
|
|
||||||
|
// Îáíîâëÿåì ïîçèöèþ ðó÷êè
|
||||||
|
UpdateResizeHandlePosition(resizableFrame, resizeHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ëîãèêà ïåðåìåùåíèÿ
|
private void OnDragPanUpdated(object sender, PanUpdatedEventArgs e, Frame frame)
|
||||||
private void OnDragPanUpdated(object sender, PanUpdatedEventArgs e, AbsoluteLayout layout)
|
|
||||||
{
|
{
|
||||||
if (isResizing) return;
|
|
||||||
|
|
||||||
if (e.StatusType == GestureStatus.Started)
|
if (e.StatusType == GestureStatus.Started)
|
||||||
{
|
{
|
||||||
startX = AbsoluteLayout.GetLayoutBounds(layout).X;
|
startX = AbsoluteLayout.GetLayoutBounds(frame).X;
|
||||||
startY = AbsoluteLayout.GetLayoutBounds(layout).Y;
|
startY = AbsoluteLayout.GetLayoutBounds(frame).Y;
|
||||||
}
|
}
|
||||||
else if (e.StatusType == GestureStatus.Running)
|
else if (e.StatusType == GestureStatus.Running)
|
||||||
{
|
{
|
||||||
double x = startX + e.TotalX;
|
double x = startX + e.TotalX;
|
||||||
double y = startY + e.TotalY;
|
double y = startY + e.TotalY;
|
||||||
|
AbsoluteLayout.SetLayoutBounds(frame, new Rect(x, y, frame.WidthRequest, frame.HeightRequest));
|
||||||
|
|
||||||
// Îáíîâëåíèå UI ÷åðåç Dispatcher
|
// Îáíîâëÿåì ïîçèöèþ ðó÷êè
|
||||||
Dispatcher.Dispatch(() =>
|
var resizeHandle = (BoxView)((Grid)frame.Content).Children[1];
|
||||||
{
|
UpdateResizeHandlePosition(frame, resizeHandle);
|
||||||
AbsoluteLayout.SetLayoutBounds(layout, new Rect(x, y, layout.WidthRequest, layout.HeightRequest));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ëîãèêà èçìåíåíèÿ ðàçìåðà
|
private void OnResizePanUpdated(object sender, PanUpdatedEventArgs e, Frame frame, BoxView resizeHandle)
|
||||||
private void OnResizePanUpdated(object sender, PanUpdatedEventArgs e, AbsoluteLayout layout)
|
|
||||||
{
|
{
|
||||||
isResizing = true;
|
|
||||||
if (e.StatusType == GestureStatus.Started)
|
if (e.StatusType == GestureStatus.Started)
|
||||||
{
|
{
|
||||||
startX = layout.WidthRequest;
|
startX = frame.WidthRequest;
|
||||||
startY = layout.HeightRequest;
|
startY = frame.HeightRequest;
|
||||||
}
|
}
|
||||||
else if (e.StatusType == GestureStatus.Running)
|
else if (e.StatusType == GestureStatus.Running)
|
||||||
{
|
{
|
||||||
double newWidth = Math.Max(50, startX + e.TotalX);
|
double newWidth = Math.Max(50, startX + e.TotalX);
|
||||||
double newHeight = Math.Max(50, startY + e.TotalY);
|
double newHeight = Math.Max(50, startY + e.TotalY);
|
||||||
|
frame.WidthRequest = newWidth;
|
||||||
|
frame.HeightRequest = newHeight;
|
||||||
|
|
||||||
Dispatcher.Dispatch(() =>
|
// Îáíîâëÿåì ïîçèöèþ ðó÷êè ïîñëå èçìåíåíèÿ ðàçìåðîâ
|
||||||
{
|
UpdateResizeHandlePosition(frame, resizeHandle);
|
||||||
layout.WidthRequest = newWidth;
|
|
||||||
layout.HeightRequest = newHeight;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else if (e.StatusType == GestureStatus.Completed || e.StatusType == GestureStatus.Canceled)
|
|
||||||
{
|
|
||||||
isResizing = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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()
|
protected override void OnAppearing()
|
||||||
{
|
{
|
||||||
base.OnAppearing();
|
base.OnAppearing();
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue