Public Access
Look the panel up, because the field the generator declares is never filled
The last commit crashed the phone before its first frame. `PhoneShell` took the `Body` field that Avalonia's name generator declares for `x:Name`, and that field is assigned in the generated `InitializeComponent` — which no view on this head calls, all of them loading their XAML directly instead. It compiles, it is null at run time, and this control dereferences it in its constructor. `TerminalScreen` has been looking its two named controls up with `FindControl` since it was written, for exactly this reason. This does the same, and the remark on the field now says why so the next person reaching for the shorter spelling finds the answer before the device does. Confirmed rather than guessed: the generator's output for this control is one method, and the assignment is inside it.
This commit is contained in:
@@ -17,6 +17,17 @@ internal sealed partial class PhoneShell : UserControl
|
||||
{
|
||||
private MainWindowViewModel? shell;
|
||||
|
||||
/// <summary>
|
||||
/// Everything the phone draws, which is the element the software keyboard is kept off.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Looked up rather than read off the field the name generator declares for <c>x:Name</c>, and
|
||||
/// <c>TerminalScreen</c> does the same for the same reason: that field is assigned by the generated
|
||||
/// <c>InitializeComponent</c>, and no view on this head calls it — they load their XAML directly. Using
|
||||
/// it compiles and is null at run time, which on this control means a crash before the first frame.
|
||||
/// </remarks>
|
||||
private readonly Panel body;
|
||||
|
||||
/// <summary>The software keyboard, while this control is attached. Null on a platform without one.</summary>
|
||||
private IInputPane? keyboard;
|
||||
|
||||
@@ -37,10 +48,12 @@ internal sealed partial class PhoneShell : UserControl
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
|
||||
// Subscribed once, for the life of the control, rather than in OnAttachedToVisualTree: Body is this
|
||||
// control's own child and cannot outlive it, and re-subscribing on every attach is how a handler
|
||||
// ends up registered twice.
|
||||
Body.SizeChanged += OnBodyResized;
|
||||
body = this.FindControl<Panel>("Body")!;
|
||||
|
||||
// Subscribed once, for the life of the control, rather than in OnAttachedToVisualTree: the panel is
|
||||
// this control's own child and cannot outlive it, and re-subscribing on every attach is how a
|
||||
// handler ends up registered twice.
|
||||
body.SizeChanged += OnBodyResized;
|
||||
|
||||
DataContextChanged += (_, _) =>
|
||||
{
|
||||
@@ -208,9 +221,9 @@ internal sealed partial class PhoneShell : UserControl
|
||||
{
|
||||
var inset = double.IsFinite(occluded) ? Math.Max(occluded, 0) : 0;
|
||||
|
||||
if (Math.Abs(Body.Margin.Bottom - inset) > 0.5)
|
||||
if (Math.Abs(body.Margin.Bottom - inset) > 0.5)
|
||||
{
|
||||
Body.Margin = new Thickness(0, 0, 0, inset);
|
||||
body.Margin = new Thickness(0, 0, 0, inset);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user