[Core] Added RootPage to NavigationPage (#464)
* d * removed whitespace * Using ArgumentNullException * changes
This commit is contained in:
Родитель
750b0346cc
Коммит
070f1dcdb5
|
@ -14,6 +14,7 @@ namespace Xamarin.Forms.Core.UnitTests
|
|||
{
|
||||
NavigationPage nav = new NavigationPage ();
|
||||
|
||||
Assert.IsNull(nav.RootPage);
|
||||
Assert.IsNull (nav.CurrentPage);
|
||||
|
||||
Label child = new Label {Text = "Label"};
|
||||
|
@ -21,7 +22,9 @@ namespace Xamarin.Forms.Core.UnitTests
|
|||
|
||||
await nav.Navigation.PushAsync (childRoot);
|
||||
|
||||
Assert.AreSame (childRoot, nav.CurrentPage);
|
||||
Assert.AreSame(childRoot, nav.RootPage);
|
||||
Assert.AreSame(childRoot, nav.CurrentPage);
|
||||
Assert.AreSame(nav.RootPage, nav.CurrentPage);
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
@ -40,16 +43,26 @@ namespace Xamarin.Forms.Core.UnitTests
|
|||
|
||||
bool fired = false;
|
||||
nav.Popped += (sender, e) => fired = true;
|
||||
|
||||
Assert.AreSame(childRoot, nav.RootPage);
|
||||
Assert.AreNotSame(childRoot2, nav.RootPage);
|
||||
Assert.AreNotSame(nav.RootPage, nav.CurrentPage);
|
||||
|
||||
var popped = await nav.Navigation.PopAsync ();
|
||||
|
||||
Assert.True (fired);
|
||||
Assert.AreSame (childRoot, nav.CurrentPage);
|
||||
Assert.AreSame(childRoot, nav.RootPage);
|
||||
Assert.AreSame(childRoot, nav.CurrentPage);
|
||||
Assert.AreSame(nav.RootPage, nav.CurrentPage);
|
||||
Assert.AreEqual (childRoot2, popped);
|
||||
|
||||
await nav.PopAsync ();
|
||||
var last = await nav.Navigation.PopAsync ();
|
||||
|
||||
Assert.IsNull (last);
|
||||
Assert.IsNotNull(nav.RootPage);
|
||||
Assert.IsNotNull(nav.CurrentPage);
|
||||
Assert.AreSame(nav.RootPage, nav.CurrentPage);
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
@ -57,6 +70,7 @@ namespace Xamarin.Forms.Core.UnitTests
|
|||
{
|
||||
NavigationPage nav = new NavigationPage ();
|
||||
|
||||
Assert.IsNull(nav.RootPage);
|
||||
Assert.IsNull (nav.CurrentPage);
|
||||
|
||||
Label child = new Label {Text = "Label"};
|
||||
|
@ -64,7 +78,9 @@ namespace Xamarin.Forms.Core.UnitTests
|
|||
|
||||
await nav.PushAsync (childRoot);
|
||||
|
||||
Assert.AreSame (childRoot, nav.CurrentPage);
|
||||
Assert.AreSame (childRoot, nav.RootPage);
|
||||
Assert.AreSame(childRoot, nav.CurrentPage);
|
||||
Assert.AreSame(nav.RootPage, nav.CurrentPage);
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
@ -96,10 +112,15 @@ namespace Xamarin.Forms.Core.UnitTests
|
|||
bool fired = false;
|
||||
nav.Pushed += (sender, e) => fired = true;
|
||||
|
||||
Assert.AreSame(childRoot, nav.RootPage);
|
||||
Assert.AreSame(childRoot, nav.CurrentPage);
|
||||
|
||||
await nav.PushAsync (childRoot);
|
||||
|
||||
Assert.False (fired);
|
||||
Assert.AreEqual (childRoot, nav.CurrentPage);
|
||||
Assert.AreSame(childRoot, nav.RootPage);
|
||||
Assert.AreSame(childRoot, nav.CurrentPage);
|
||||
Assert.AreSame(nav.RootPage, nav.CurrentPage);
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
@ -184,7 +205,9 @@ namespace Xamarin.Forms.Core.UnitTests
|
|||
nav.PopToRootAsync ();
|
||||
|
||||
Assert.True (signaled);
|
||||
Assert.AreEqual (root, nav.CurrentPage);
|
||||
Assert.AreSame (root, nav.RootPage);
|
||||
Assert.AreSame(root, nav.CurrentPage);
|
||||
Assert.AreSame(nav.RootPage, nav.CurrentPage);
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
@ -209,7 +232,9 @@ namespace Xamarin.Forms.Core.UnitTests
|
|||
Assert.AreEqual (2, poppedChildren.Count);
|
||||
Assert.Contains (child1, poppedChildren);
|
||||
Assert.Contains (child2, poppedChildren);
|
||||
Assert.AreEqual (root, nav.CurrentPage);
|
||||
Assert.AreSame(root, nav.RootPage);
|
||||
Assert.AreSame(root, nav.CurrentPage);
|
||||
Assert.AreSame(nav.RootPage, nav.CurrentPage);
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
@ -458,6 +483,72 @@ namespace Xamarin.Forms.Core.UnitTests
|
|||
Assert.False (result);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestInsertPage()
|
||||
{
|
||||
var root = new ContentPage { Title = "Root" };
|
||||
var newPage = new ContentPage();
|
||||
var navPage = new NavigationPage(root);
|
||||
|
||||
navPage.Navigation.InsertPageBefore(newPage, navPage.RootPage);
|
||||
|
||||
Assert.AreSame(newPage, navPage.RootPage);
|
||||
Assert.AreNotSame(newPage, navPage.CurrentPage);
|
||||
Assert.AreNotSame(navPage.RootPage, navPage.CurrentPage);
|
||||
Assert.AreSame(root, navPage.CurrentPage);
|
||||
|
||||
Assert.Throws<ArgumentException>(() =>
|
||||
{
|
||||
navPage.Navigation.InsertPageBefore(new ContentPage(), new ContentPage());
|
||||
});
|
||||
|
||||
Assert.Throws<ArgumentException>(() =>
|
||||
{
|
||||
navPage.Navigation.InsertPageBefore(navPage.RootPage, navPage.CurrentPage);
|
||||
});
|
||||
|
||||
Assert.Throws<ArgumentNullException>(() =>
|
||||
{
|
||||
navPage.Navigation.InsertPageBefore(null, navPage.CurrentPage);
|
||||
});
|
||||
|
||||
Assert.Throws<ArgumentNullException>(() =>
|
||||
{
|
||||
navPage.Navigation.InsertPageBefore(new ContentPage(), null);
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async void TestRemovePage()
|
||||
{
|
||||
var root = new ContentPage { Title = "Root" };
|
||||
var newPage = new ContentPage();
|
||||
var navPage = new NavigationPage(root);
|
||||
await navPage.PushAsync(newPage);
|
||||
|
||||
navPage.Navigation.RemovePage(root);
|
||||
|
||||
Assert.AreSame(newPage, navPage.RootPage);
|
||||
Assert.AreSame(newPage, navPage.CurrentPage);
|
||||
Assert.AreSame(navPage.RootPage, navPage.CurrentPage);
|
||||
Assert.AreNotSame(root, navPage.CurrentPage);
|
||||
|
||||
Assert.Throws<ArgumentException>(() =>
|
||||
{
|
||||
navPage.Navigation.RemovePage(root);
|
||||
});
|
||||
|
||||
Assert.Throws<InvalidOperationException>(() =>
|
||||
{
|
||||
navPage.Navigation.RemovePage(newPage);
|
||||
});
|
||||
|
||||
Assert.Throws<ArgumentNullException>(() =>
|
||||
{
|
||||
navPage.Navigation.RemovePage(null);
|
||||
});
|
||||
}
|
||||
|
||||
[Test (Description = "CurrentPage should not be set to null when you attempt to pop the last page")]
|
||||
[Property ("Bugzilla", 28335)]
|
||||
public async Task CurrentPageNotNullPoppingRoot()
|
||||
|
|
|
@ -28,7 +28,10 @@ namespace Xamarin.Forms
|
|||
|
||||
static readonly BindablePropertyKey CurrentPagePropertyKey = BindableProperty.CreateReadOnly("CurrentPage", typeof(Page), typeof(NavigationPage), null);
|
||||
public static readonly BindableProperty CurrentPageProperty = CurrentPagePropertyKey.BindableProperty;
|
||||
|
||||
|
||||
static readonly BindablePropertyKey RootPagePropertyKey = BindableProperty.CreateReadOnly(nameof(RootPage), typeof(Page), typeof(NavigationPage), null);
|
||||
public static readonly BindableProperty RootPageProperty = RootPagePropertyKey.BindableProperty;
|
||||
|
||||
public NavigationPage()
|
||||
{
|
||||
_platformConfigurationRegistry = new Lazy<PlatformConfigurationRegistry<NavigationPage>>(() => new PlatformConfigurationRegistry<NavigationPage>(this));
|
||||
|
@ -92,6 +95,12 @@ namespace Xamarin.Forms
|
|||
private set { SetValue(CurrentPagePropertyKey, value); }
|
||||
}
|
||||
|
||||
public Page RootPage
|
||||
{
|
||||
get { return (Page)GetValue(RootPageProperty); }
|
||||
private set { SetValue(RootPagePropertyKey, value); }
|
||||
}
|
||||
|
||||
public static string GetBackButtonTitle(BindableObject page)
|
||||
{
|
||||
return (string)page.GetValue(BackButtonTitleProperty);
|
||||
|
@ -304,8 +313,14 @@ namespace Xamarin.Forms
|
|||
|
||||
void InsertPageBefore(Page page, Page before)
|
||||
{
|
||||
if (page == null)
|
||||
throw new ArgumentNullException($"{nameof(page)} cannot be null.");
|
||||
|
||||
if (before == null)
|
||||
throw new ArgumentNullException($"{nameof(before)} cannot be null.");
|
||||
|
||||
if (!PageController.InternalChildren.Contains(before))
|
||||
throw new ArgumentException("before must be a child of the NavigationPage", "before");
|
||||
throw new ArgumentException($"{nameof(before)} must be a child of the NavigationPage", nameof(before));
|
||||
|
||||
if (PageController.InternalChildren.Contains(page))
|
||||
throw new ArgumentException("Cannot insert page which is already in the navigation stack");
|
||||
|
@ -316,6 +331,9 @@ namespace Xamarin.Forms
|
|||
int index = PageController.InternalChildren.IndexOf(before);
|
||||
PageController.InternalChildren.Insert(index, page);
|
||||
|
||||
if (index == 0)
|
||||
RootPage = page;
|
||||
|
||||
// Shouldn't be required?
|
||||
if (Width > 0 && Height > 0)
|
||||
ForceLayout();
|
||||
|
@ -326,15 +344,13 @@ namespace Xamarin.Forms
|
|||
if (((INavigationPageController)this).StackDepth == 1)
|
||||
return;
|
||||
|
||||
var root = (Page)PageController.InternalChildren.First();
|
||||
|
||||
var childrenToRemove = PageController.InternalChildren.ToArray().Where(c => c != root);
|
||||
foreach (var child in childrenToRemove)
|
||||
Element[] childrenToRemove = PageController.InternalChildren.Skip(1).ToArray();
|
||||
foreach (Element child in childrenToRemove)
|
||||
PageController.InternalChildren.Remove(child);
|
||||
|
||||
CurrentPage = root;
|
||||
CurrentPage = RootPage;
|
||||
|
||||
var args = new NavigationRequestedEventArgs(root, animated);
|
||||
var args = new NavigationRequestedEventArgs(RootPage, animated);
|
||||
|
||||
EventHandler<NavigationRequestedEventArgs> requestPopToRoot = PopToRootRequestedInternal;
|
||||
if (requestPopToRoot != null)
|
||||
|
@ -345,8 +361,7 @@ namespace Xamarin.Forms
|
|||
await args.Task;
|
||||
}
|
||||
|
||||
if (PoppedToRoot != null)
|
||||
PoppedToRoot(this, new PoppedToRootEventArgs(root, childrenToRemove.OfType<Page>().ToList()));
|
||||
PoppedToRoot?.Invoke(this, new PoppedToRootEventArgs(RootPage, childrenToRemove.OfType<Page>().ToList()));
|
||||
}
|
||||
|
||||
async Task PushAsyncInner(Page page, bool animated)
|
||||
|
@ -367,24 +382,29 @@ namespace Xamarin.Forms
|
|||
await args.Task;
|
||||
}
|
||||
|
||||
if (Pushed != null)
|
||||
Pushed(this, args);
|
||||
Pushed?.Invoke(this, args);
|
||||
}
|
||||
|
||||
void PushPage(Page page)
|
||||
{
|
||||
PageController.InternalChildren.Add(page);
|
||||
|
||||
if (PageController.InternalChildren.Count == 1)
|
||||
RootPage = page;
|
||||
|
||||
CurrentPage = page;
|
||||
}
|
||||
|
||||
void RemovePage(Page page)
|
||||
{
|
||||
if (page == CurrentPage && ((INavigationPageController)this).StackDepth <= 1)
|
||||
if (page == null)
|
||||
throw new ArgumentNullException($"{nameof(page)} cannot be null.");
|
||||
|
||||
if (page == CurrentPage && CurrentPage == RootPage)
|
||||
throw new InvalidOperationException("Cannot remove root page when it is also the currently displayed page.");
|
||||
if (page == CurrentPage)
|
||||
{
|
||||
Log.Warning("NavigationPage", "RemovePage called for CurrentPage object. This can result in undesired behavior, consider called PopAsync instead.");
|
||||
Log.Warning("NavigationPage", "RemovePage called for CurrentPage object. This can result in undesired behavior, consider calling PopAsync instead.");
|
||||
PopAsync();
|
||||
return;
|
||||
}
|
||||
|
@ -393,10 +413,11 @@ namespace Xamarin.Forms
|
|||
throw new ArgumentException("Page to remove must be contained on this Navigation Page");
|
||||
|
||||
EventHandler<NavigationRequestedEventArgs> handler = RemovePageRequestedInternal;
|
||||
if (handler != null)
|
||||
handler(this, new NavigationRequestedEventArgs(page, true));
|
||||
handler?.Invoke(this, new NavigationRequestedEventArgs(page, true));
|
||||
|
||||
PageController.InternalChildren.Remove(page);
|
||||
if (RootPage == page)
|
||||
RootPage = (Page)PageController.InternalChildren.First();
|
||||
}
|
||||
|
||||
void SafePop()
|
||||
|
|
|
@ -226,6 +226,42 @@
|
|||
</remarks>
|
||||
</Docs>
|
||||
</Member>
|
||||
<Member MemberName="RootPage">
|
||||
<MemberSignature Language="C#" Value="public Xamarin.Forms.Page RootPage { get; }" />
|
||||
<MemberSignature Language="ILAsm" Value=".property instance class Xamarin.Forms.Page RootPage" />
|
||||
<MemberType>Property</MemberType>
|
||||
<AssemblyInfo>
|
||||
<AssemblyVersion>2.0.0.0</AssemblyVersion>
|
||||
</AssemblyInfo>
|
||||
<ReturnValue>
|
||||
<ReturnType>Xamarin.Forms.Page</ReturnType>
|
||||
</ReturnValue>
|
||||
<Docs>
|
||||
<summary>
|
||||
The <see cref="T:Xamarin.Forms.Page" /> that is the root of the navigation stack.
|
||||
</summary>
|
||||
<value>To be added.</value>
|
||||
<remarks>To be added.</remarks>
|
||||
</Docs>
|
||||
</Member>
|
||||
<Member MemberName="RootPageProperty">
|
||||
<MemberSignature Language="C#" Value="public static readonly Xamarin.Forms.BindableProperty RootPageProperty;" />
|
||||
<MemberSignature Language="ILAsm" Value=".field public static initonly class Xamarin.Forms.BindableProperty RootPageProperty" />
|
||||
<MemberType>Field</MemberType>
|
||||
<AssemblyInfo>
|
||||
<AssemblyVersion>2.0.0.0</AssemblyVersion>
|
||||
</AssemblyInfo>
|
||||
<ReturnValue>
|
||||
<ReturnType>Xamarin.Forms.BindableProperty</ReturnType>
|
||||
</ReturnValue>
|
||||
<Docs>
|
||||
<summary>
|
||||
Identifies the <see cref="P:Xamarin.Forms.NavigationPage.RootPage" /> property.
|
||||
</summary>
|
||||
<remarks>
|
||||
</remarks>
|
||||
</Docs>
|
||||
</Member>
|
||||
<Member MemberName="GetBackButtonTitle">
|
||||
<MemberSignature Language="C#" Value="public static string GetBackButtonTitle (Xamarin.Forms.BindableObject page);" />
|
||||
<MemberSignature Language="ILAsm" Value=".method public static hidebysig string GetBackButtonTitle(class Xamarin.Forms.BindableObject page) cil managed" />
|
||||
|
|
Загрузка…
Ссылка в новой задаче