Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Obsolete setting mainpage via application #23692

Merged
merged 16 commits into from
Jul 23, 2024
2 changes: 1 addition & 1 deletion src/Compatibility/ControlGallery/src/iOS/AppDelegate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ public void StartPressed40911()

button.TouchUpInside += (sender, e) =>
{
Maui.Controls.Application.Current.MainPage = new ContentPage { Content = new Label { Text = "40911 Success" } };
Maui.Controls.Application.Current.Windows[0].Page = new ContentPage { Content = new Label { Text = "40911 Success" } };
loginViewController.DismissViewController(true, null);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public BasePage()
{
if (SelectedItem != null)
{
if (Application.Current.MainPage is FlyoutPage fp)
if (this.Window.Page is FlyoutPage fp)
await fp.Detail.Navigation.PushAsync(PreparePage(SelectedItem));
else
await Navigation.PushAsync(PreparePage(SelectedItem));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ void OnSetToBottomTabs(object sender, EventArgs e)

SetNewMainPage(bottomTabs);
AndroidSpecific.TabbedPage.SetToolbarPlacement(bottomTabs, AndroidSpecific.ToolbarPlacement.Bottom);
Application.Current!.MainPage = bottomTabs;
this.Window!.Page = bottomTabs;
}

void OnChangeTabIndex(object sender, EventArgs e)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace Maui.Controls.Sample.Pages
public partial class FlyoutPageGallery
{

FlyoutPage? FlyoutPage => Application.Current!.MainPage as FlyoutPage;
FlyoutPage? FlyoutPage => this.Window!.Page as FlyoutPage;
public FlyoutPageGallery()
{
InitializeComponent();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ namespace Maui.Controls.Sample.Pages.ShellGalleries
{
public partial class ShellChromeGallery
{
AppShell? AppShell => Application.Current!.MainPage as AppShell;
AppShell? AppShell => this.Window!.Page as AppShell;

public ShellChromeGallery()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public iOSTranslucentNavigationBarPage(ICommand restore)

void OnTranslucentNavigationBarButtonClicked(object sender, EventArgs e)
{
(Microsoft.Maui.Controls.Application.Current!.MainPage as Microsoft.Maui.Controls.NavigationPage)!.On<iOS>().SetIsNavigationBarTranslucent(!(Microsoft.Maui.Controls.Application.Current!.MainPage as Microsoft.Maui.Controls.NavigationPage)!.On<iOS>().IsNavigationBarTranslucent());
(this.Window!.Page as Microsoft.Maui.Controls.NavigationPage)!.On<iOS>().SetIsNavigationBarTranslucent(!(this.Window!.Page as Microsoft.Maui.Controls.NavigationPage)!.On<iOS>().IsNavigationBarTranslucent());
}

void OnReturnButtonClicked(object sender, EventArgs e)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ void OnTapGestureRecognizerTapped(object sender, EventArgs args)

void OnRTLToggled(object sender, ToggledEventArgs e)
{
var mainPage = Application.Current!.MainPage;
var mainPage = this.Window!.Page;

if (mainPage == null)
return;
Expand Down
6 changes: 6 additions & 0 deletions src/Controls/src/Core/Application/Application.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,13 +85,15 @@ public IAppLinks AppLinks
/// <include file="../../docs/Microsoft.Maui.Controls/Application.xml" path="//Member[@MemberName='MainPage']/Docs/*" />
public Page? MainPage
{
[Obsolete("This property has been deprecated. For single-window applications, use Windows[0].Page. For multi-window applications, identify and use the appropriate Window object to access the desired Page. Additionally, each element features a Window property, accessible when it's part of the current window.")]
get
{
if (Windows.Count == 0)
return _singleWindowMainPage;

return Windows[0].Page;
}
[Obsolete("This property is deprecated. Initialize your application by overriding Application.CreateWindow rather than setting MainPage. To modify the root page in an active application, use Windows[0].Page for applications with a single window. For applications with multiple windows, use Application.Windows to identify and update the root page on the correct window. Additionally, each element features a Window property, accessible when it's part of the current window.")]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking out loud - this will cause a warning (or possibly error) in 100% of MAUI applications ever written, no? Is it that bad to keep this? Maybe an analyzer could be used to flag it and rewrite the code for those interested? (And ignored by those who don't.)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea, I just worry about also dragging the past along with us and not overall widening the pit of success

From a library author perspective using these APIs is really bad. For example, none of this code from our toolkit will work for multi-window https://github.com/CommunityToolkit/Maui/blob/cc1fb686815587076bbad45a1903f3ec3039315d/src/CommunityToolkit.Maui/PopupService.cs#L17

We probably see an issue a month for android where users need to override CreateWindow

#23645
#23493

I also worry about new users using MainPage and ignoring the analyzer suggestions.

The fix here is basically to do a solution search for
MainPage and replace it with Windows[0].Page

I get it because how widespread it is that users will all see warnings, but, it just seems to put MAUI in general on a path to longer term refinement/success.

I could see us maybe Obsoleting the set and just using an analyzer on the get perhaps?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Existing non-trivial apps already have various workarounds. There are still various gotchas in APIs. It's been getting better but it's not like there are no sharp edges.

Given that MAUI is relatively young, personally, I would be more radical, especially if it can lead to people not hitting bugs in the future (which translates to not losing more resources).

Analyzer might be nice in the sense: fix it for me fast.

set
{
if (MainPage == value)
Expand Down Expand Up @@ -513,15 +515,19 @@ protected virtual Window CreateWindow(IActivationState? activationState)
return window;

if (Windows.Count > 1)
#pragma warning disable CS0618 // Type or member is obsolete
throw new NotImplementedException($"Either set {nameof(MainPage)} or override {nameof(Application.CreateWindow)}.");
#pragma warning restore CS0618 // Type or member is obsolete

if (Windows.Count > 0)
return Windows[0];

if (_singleWindowMainPage is not null)
return new Window(_singleWindowMainPage);

#pragma warning disable CS0618 // Type or member is obsolete
throw new NotImplementedException($"Either set {nameof(MainPage)} or override {nameof(Application.CreateWindow)}.");
#pragma warning restore CS0618 // Type or member is obsolete
}

void AddWindow(Window window)
Expand Down
45 changes: 41 additions & 4 deletions src/Controls/src/Core/Shell/Shell.cs
Original file line number Diff line number Diff line change
Expand Up @@ -950,14 +950,51 @@ public static Shell Current
{
get
{
if (Application.Current == null)
if (Application.Current is null || Application.Current.Windows.Count == 0)
return null;

if (Application.Current.Windows.Count == 1)
{
return Application.Current.Windows[0].Page as Shell;
}

// Check if shell is activated
Shell currentShell = null;
Shell returnIfThereIsJustOneShell = null;
bool tooManyShells = false;
foreach (var window in Application.Current.Windows)
if (window is Window && window.IsActivated && window.Page is Shell shell)
return shell;
{
if (window.Page is Shell shell)
{
if (window.IsActivated)
{
if(currentShell is not null)
{
currentShell = null;
break;
}

currentShell = shell;
}

if (returnIfThereIsJustOneShell is not null)
{
tooManyShells = true;
}
}
}

if (currentShell is not null)
{
return currentShell;
}

if (!tooManyShells && returnIfThereIsJustOneShell is not null)
{
return returnIfThereIsJustOneShell;
}

return Application.Current?.MainPage as Shell;
throw new InvalidOperationException($"Unable to determine the current Shell instance you want to use. Please access Shell via the Windows property on {Application.Current.GetType()}.");
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,9 @@ public async Task ChangingToNewMauiContextDoesntCrash(bool useAppMainPage, Type
if (useAppMainPage)
{
var app = ApplicationServices.GetService<IApplication>() as ApplicationStub;
#pragma warning disable CS0618 // Type or member is obsolete
app.MainPage = rootPage;
#pragma warning restore CS0618 // Type or member is obsolete
window = await InvokeOnMainThreadAsync(() => (app as IApplication).CreateWindow(null));

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ public CorePageView(Page rootPage)
var realize = page.Realize();
if (realize is Shell)
{
Application.Current.MainPage = realize;
this.Window.Page = realize;
}
else
{
Expand Down
Loading
Loading