Merge pull request #452 from WCKYWCKF/A-few-minor-issues

Fixed: Closing a dialog returns TView to the user instead of occupying its parent.
This commit is contained in:
Dong Bin
2024-10-31 12:16:01 +08:00
committed by GitHub
4 changed files with 107 additions and 17 deletions

View File

@@ -35,6 +35,12 @@ public abstract class OverlayFeedbackElement : ContentControl
ClosedEvent.AddClassHandler<OverlayFeedbackElement>((o, e) => o.OnClosed(e)); ClosedEvent.AddClassHandler<OverlayFeedbackElement>((o, e) => o.OnClosed(e));
} }
protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e)
{
base.OnDetachedFromVisualTree(e);
Content = null;
}
public bool IsClosed public bool IsClosed
{ {
get => GetValue(IsClosedProperty); get => GetValue(IsClosedProperty);
@@ -133,9 +139,11 @@ public abstract class OverlayFeedbackElement : ContentControl
var left = Canvas.GetLeft(this); var left = Canvas.GetLeft(this);
var top = Canvas.GetTop(this); var top = Canvas.GetTop(this);
var width = _windowEdge is WindowEdge.West or WindowEdge.NorthWest or WindowEdge.SouthWest var width = _windowEdge is WindowEdge.West or WindowEdge.NorthWest or WindowEdge.SouthWest
? Bounds.Width : _resizeDragStartBounds.Width; ? Bounds.Width
: _resizeDragStartBounds.Width;
var height = _windowEdge is WindowEdge.North or WindowEdge.NorthEast or WindowEdge.NorthWest var height = _windowEdge is WindowEdge.North or WindowEdge.NorthEast or WindowEdge.NorthWest
? Bounds.Height : _resizeDragStartBounds.Height; ? Bounds.Height
: _resizeDragStartBounds.Height;
var newBounds = CalculateNewBounds(left, top, width, height, diff, ContainerPanel?.Bounds, _windowEdge.Value); var newBounds = CalculateNewBounds(left, top, width, height, diff, ContainerPanel?.Bounds, _windowEdge.Value);
Canvas.SetLeft(this, newBounds.Left); Canvas.SetLeft(this, newBounds.Left);
Canvas.SetTop(this, newBounds.Top); Canvas.SetTop(this, newBounds.Top);
@@ -144,37 +152,49 @@ public abstract class OverlayFeedbackElement : ContentControl
AnchorAndUpdatePositionInfo(); AnchorAndUpdatePositionInfo();
} }
private Rect CalculateNewBounds(double left, double top, double width, double height, Vector diff, Rect? containerBounds, private Rect CalculateNewBounds(double left, double top, double width, double height, Vector diff,
Rect? containerBounds,
WindowEdge windowEdge) WindowEdge windowEdge)
{ {
diff = CoerceDelta(left, top, width, height, diff, containerBounds, windowEdge); diff = CoerceDelta(left, top, width, height, diff, containerBounds, windowEdge);
switch (windowEdge) switch (windowEdge)
{ {
case WindowEdge.North: case WindowEdge.North:
top += diff.Y; height -= diff.Y; top += diff.Y;
height -= diff.Y;
break; break;
case WindowEdge.NorthEast: case WindowEdge.NorthEast:
top += diff.Y; width += diff.X; height -= diff.Y; top += diff.Y;
width += diff.X;
height -= diff.Y;
break; break;
case WindowEdge.East: case WindowEdge.East:
width += diff.X; width += diff.X;
break; break;
case WindowEdge.SouthEast: case WindowEdge.SouthEast:
width += diff.X; height += diff.Y; width += diff.X;
height += diff.Y;
break; break;
case WindowEdge.South: case WindowEdge.South:
height += diff.Y; height += diff.Y;
break; break;
case WindowEdge.SouthWest: case WindowEdge.SouthWest:
left += diff.X; width -= diff.X; height += diff.Y; left += diff.X;
width -= diff.X;
height += diff.Y;
break; break;
case WindowEdge.West: case WindowEdge.West:
left += diff.X; width -= diff.X; left += diff.X;
width -= diff.X;
break; break;
case WindowEdge.NorthWest: case WindowEdge.NorthWest:
left += diff.X; top += diff.Y; width -= diff.X; height -= diff.Y; left += diff.X;
top += diff.Y;
width -= diff.X;
height -= diff.Y;
break; break;
} }
return new Rect(left, top, width, height); return new Rect(left, top, width, height);
} }
@@ -189,10 +209,10 @@ public abstract class OverlayFeedbackElement : ContentControl
? -top ? -top
: -height; : -height;
var maxX = windowEdge is WindowEdge.West or WindowEdge.NorthWest or WindowEdge.SouthWest var maxX = windowEdge is WindowEdge.West or WindowEdge.NorthWest or WindowEdge.SouthWest
? width-MinWidth ? width - MinWidth
: containerBounds.Value.Width - left - width; : containerBounds.Value.Width - left - width;
var maxY = windowEdge is WindowEdge.North or WindowEdge.NorthEast or WindowEdge.NorthWest var maxY = windowEdge is WindowEdge.North or WindowEdge.NorthEast or WindowEdge.NorthWest
? height-MinWidth ? height - MinWidth
: containerBounds.Value.Height - top - height; : containerBounds.Value.Height - top - height;
return new Vector(MathHelpers.SafeClamp(diff.X, minX, maxX), MathHelpers.SafeClamp(diff.Y, minY, maxY)); return new Vector(MathHelpers.SafeClamp(diff.X, minX, maxX), MathHelpers.SafeClamp(diff.Y, minY, maxY));
} }

View File

@@ -0,0 +1,27 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Headless;
using Avalonia.Headless.XUnit;
using Avalonia.Input;
using Avalonia.Threading;
namespace HeadlessTest.Ursa.Controls.OverlayShared.Case_Close_Dialog_Clear_Content_Parent;
public class Test
{
[AvaloniaFact]
public void Dialog_Parent_Is_Cleared_After_Close()
{
var ursaWindow = new TestWindow();
ursaWindow.Show();
var button = ursaWindow.FindControl<Button>("button");
ursaWindow.MouseDown(new Point(280, 400), MouseButton.Left);
ursaWindow.MouseUp(new Point(280, 400), MouseButton.Left);
Dispatcher.UIThread.RunJobs();
var parent = ursaWindow.TextBox.Parent;
Assert.NotNull(ursaWindow.TextBox.Parent);
ursaWindow.DialogViewModel.Close();
Dispatcher.UIThread.RunJobs();
Assert.Null(ursaWindow.TextBox.Parent);
}
}

View File

@@ -0,0 +1,11 @@
<u:UrsaWindow xmlns="https://github.com/avaloniaui"
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:u="https://irihi.tech/ursa"
mc:Ignorable="d" d:DesignWidth="800"
d:DesignHeight="450"
x:Class="HeadlessTest.Ursa.Controls.OverlayShared.Case_Close_Dialog_Clear_Content_Parent.TestWindow"
Title="TestWindow">
<Button HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Name="button" Content="Click" Click="Button_OnClick"></Button>
</u:UrsaWindow>

View File

@@ -0,0 +1,32 @@
using Avalonia.Controls;
using Avalonia.Interactivity;
using Irihi.Avalonia.Shared.Contracts;
using Ursa.Controls;
namespace HeadlessTest.Ursa.Controls.OverlayShared.Case_Close_Dialog_Clear_Content_Parent;
public partial class TestWindow : UrsaWindow
{
public TestWindow()
{
InitializeComponent();
}
internal TextBox TextBox = new TextBox();
internal DialogViewModel DialogViewModel = new DialogViewModel();
private void Button_OnClick(object? sender, RoutedEventArgs e)
{
OverlayDialog.Show(TextBox, DialogViewModel);
}
}
class DialogViewModel : IDialogContext
{
public void Close()
{
RequestClose?.Invoke(this, null);
}
public event EventHandler<object?>? RequestClose;
}