{"record":{"id":"6072573beb2b8cd1","repo":"dotnet/maui","slug":"flyout-must-be-set-before-using-a-flyoutpage","errorCode":null,"errorMessage":"Flyout must be set before using a FlyoutPage","messagePattern":"Flyout must be set before using a FlyoutPage","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Controls/src/Core/FlyoutPage/FlyoutPage.cs","lineNumber":177,"sourceCode":"\t\tRect IFlyoutPageController.DetailBounds\n\t\t{\n\t\t\tget { return _detailBounds; }\n\t\t\tset\n\t\t\t{\n\t\t\t\t_detailBounds = value;\n\t\t\t\tif (_detail == null)\n\t\t\t\t\tthrow new InvalidOperationException(\"Detail must be set before using a FlyoutPage\");\n\t\t\t}\n\t\t}\n\n\t\tRect IFlyoutPageController.FlyoutBounds\n\t\t{\n\t\t\tget { return _flyoutBounds; }\n\t\t\tset\n\t\t\t{\n\t\t\t\t_flyoutBounds = value;\n\t\t\t\tif (_flyout == null)\n\t\t\t\t\tthrow new InvalidOperationException(\"Flyout must be set before using a FlyoutPage\");\n\t\t\t}\n\t\t}\n\n\t\tbool IFlyoutPageController.ShouldShowSplitMode\n\t\t{\n\t\t\tget\n\t\t\t{\n\t\t\t\tif (DeviceInfo.Idiom == DeviceIdiom.Phone)\n\t\t\t\t\treturn false;\n\n\t\t\t\tFlyoutLayoutBehavior behavior = FlyoutLayoutBehavior;\n\t\t\t\tvar orientation = Window.GetOrientation();\n\n\t\t\t\tbool isSplitOnLandscape = (behavior == FlyoutLayoutBehavior.SplitOnLandscape || behavior == FlyoutLayoutBehavior.Default) && orientation.IsLandscape();\n\t\t\t\tbool isSplitOnPortrait = behavior == FlyoutLayoutBehavior.SplitOnPortrait && orientation.IsPortrait();\n\t\t\t\treturn behavior == FlyoutLayoutBehavior.Split || isSplitOnLandscape || isSplitOnPortrait;\n\t\t\t}\n\t\t}","sourceCodeStart":159,"sourceCodeEnd":195,"githubUrl":"https://github.com/dotnet/maui/blob/f377ff1c5ee04d334d8a925f50c83a6b7afddf03/src/Controls/src/Core/FlyoutPage/FlyoutPage.cs#L159-L195","documentation":"The IFlyoutPageController.FlyoutBounds setter throws InvalidOperationException when the renderer reports flyout layout bounds but Flyout was never assigned. Symmetric with DetailBounds: platform renderers push the measured flyout rect during layout, and a null Flyout means setup is incomplete.","triggerScenarios":"A FlyoutPage is laid out by the platform before its Flyout property is set, or a custom renderer assigns FlyoutBounds while Flyout is null.","commonSituations":"Setting Detail but forgetting Flyout, or a renderer that measures the master pane before the flyout page exists.","solutions":["Set Flyout (with a non-empty Title) and Detail before the page enters the visual tree.","In custom renderers, defer FlyoutBounds assignment until Flyout is non-null.","Use a factory/builder that validates both children are present."],"exampleFix":"// before\nMainPage = new FlyoutPage { Detail = detail };\n// renderer sets FlyoutBounds -> throws\n\n// after\nMainPage = new FlyoutPage { Flyout = new ContentPage{Title=\"Menu\"}, Detail = detail };","handlingStrategy":"validation","validationCode":"if (flyoutPage.Flyout is null) throw new InvalidOperationException(\"Set Flyout before layout\");","typeGuard":"static bool IsFlyoutPageReady(FlyoutPage p) => p.Flyout is not null && p.Detail is not null;","tryCatchPattern":null,"preventionTips":["Set both Flyout (with Title) and Detail before navigating to the page.","Defer FlyoutBounds assignment in custom renderers until Flyout is non-null.","Validate setup in a builder before pushing the page."],"tags":["maui","flyoutpage","renderers","layout"],"backgroundTag":null,"analyzedSha":"f377ff1c5ee04d334d8a925f50c83a6b7afddf03","analyzedAt":"2026-08-13T14:26:18.069Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}