-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathSizedFrame.cs
67 lines (53 loc) · 2.23 KB
/
SizedFrame.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
using System;
using Windows.Foundation;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
namespace Coder.Desktop.App.Controls;
public class SizedFrameEventArgs : EventArgs
{
public Size NewSize { get; init; }
}
/// <summary>
/// SizedFrame extends Frame by adding a SizeChanged event, which will be triggered when:
/// - The contained Page's content's size changes
/// - We switch to a different page.
/// Sadly this is necessary because Window.Content.SizeChanged doesn't trigger when the Page's content changes.
/// </summary>
public class SizedFrame : Frame
{
public delegate void SizeChangeDelegate(object sender, SizedFrameEventArgs e);
public new event SizeChangeDelegate? SizeChanged;
private Size _lastSize;
public void SetPage(Page page)
{
if (ReferenceEquals(page, Content)) return;
// Set the new event listener.
if (page.Content is not FrameworkElement newElement)
throw new Exception("Failed to get Page.Content as FrameworkElement on SizedFrame navigation");
newElement.SizeChanged += Content_SizeChanged;
// Unset the previous event listener.
if (Content is Page { Content: FrameworkElement oldElement })
oldElement.SizeChanged -= Content_SizeChanged;
// We don't use RootFrame.Navigate here because it doesn't let you
// instantiate the page yourself. We also don't need forwards/backwards
// capabilities.
Content = page;
// Fire an event.
Content_SizeChanged(newElement, null);
}
public Size GetContentSize()
{
if (Content is not Page { Content: FrameworkElement frameworkElement })
throw new Exception("Failed to get Content as FrameworkElement for SizedFrame");
frameworkElement.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
return new Size(frameworkElement.ActualWidth, frameworkElement.ActualHeight);
}
private void Content_SizeChanged(object sender, SizeChangedEventArgs? _)
{
var size = GetContentSize();
if (size == _lastSize) return;
_lastSize = size;
var args = new SizedFrameEventArgs { NewSize = size };
SizeChanged?.Invoke(this, args);
}
}