Merge branch '4.7.0'
# Conflicts: # Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems
This commit is contained in:
Коммит
719fc7a604
|
@ -92,6 +92,8 @@ namespace Xamarin.Forms.ControlGallery.Android
|
|||
return null;
|
||||
});
|
||||
|
||||
DependencyService.Register<IMultiWindowService, MultiWindowService>();
|
||||
|
||||
LoadApplication(_app);
|
||||
|
||||
#if !TEST_EXPERIMENTAL_RENDERERS
|
||||
|
@ -103,6 +105,11 @@ namespace Xamarin.Forms.ControlGallery.Android
|
|||
#endif
|
||||
}
|
||||
|
||||
public void ReloadApplication()
|
||||
{
|
||||
LoadApplication(_app);
|
||||
}
|
||||
|
||||
protected override void OnResume()
|
||||
{
|
||||
base.OnResume();
|
||||
|
@ -114,7 +121,26 @@ namespace Xamarin.Forms.ControlGallery.Android
|
|||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
[Java.Interop.Export("BackgroundApp")]
|
||||
public void BackgroundApp()
|
||||
{
|
||||
Intent intent = new Intent();
|
||||
intent.SetAction(Intent.ActionMain);
|
||||
intent.AddCategory(Intent.CategoryHome);
|
||||
this.StartActivity(intent);
|
||||
}
|
||||
|
||||
[Java.Interop.Export("ForegroundApp")]
|
||||
public void ForegroundApp()
|
||||
{
|
||||
// this only works pre API 29
|
||||
Intent intent = new Intent(ApplicationContext, typeof(Activity1));
|
||||
intent.SetAction(Intent.ActionMain);
|
||||
intent.AddCategory(Intent.CategoryLauncher);
|
||||
this.ApplicationContext.StartActivity(intent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
|
@ -0,0 +1,106 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.Content.PM;
|
||||
using Android.OS;
|
||||
using Android.Renderscripts;
|
||||
using Android.Runtime;
|
||||
using Android.Views;
|
||||
using Android.Widget;
|
||||
using Xamarin.Forms.Controls.Issues;
|
||||
|
||||
namespace Xamarin.Forms.ControlGallery.Android
|
||||
{
|
||||
[Activity(Label = "Issue10182Activity", Icon = "@drawable/icon", Theme = "@style/MyTheme",
|
||||
MainLauncher = false, HardwareAccelerated = true,
|
||||
ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize | ConfigChanges.UiMode)]
|
||||
public class Issue10182Activity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
|
||||
{
|
||||
Activity1 _activity1;
|
||||
protected override void OnCreate(Bundle savedInstanceState)
|
||||
{
|
||||
var currentApplication = Xamarin.Forms.Application.Current;
|
||||
TabLayoutResource = Resource.Layout.Tabbar;
|
||||
ToolbarResource = Resource.Layout.Toolbar;
|
||||
|
||||
base.OnCreate(savedInstanceState);
|
||||
|
||||
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
|
||||
LoadApplication(new Issue10182Application());
|
||||
|
||||
_activity1 = (Activity1)DependencyService.Resolve<Context>();
|
||||
|
||||
Device.BeginInvokeOnMainThread(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
await Task.Delay(1000);
|
||||
{
|
||||
Intent intent = new Intent(_activity1, typeof(Activity1));
|
||||
intent.AddFlags(ActivityFlags.ReorderToFront);
|
||||
_activity1.StartActivity(intent);
|
||||
}
|
||||
|
||||
await Task.Delay(1000);
|
||||
{
|
||||
Intent intent = new Intent(this, typeof(Issue10182Activity));
|
||||
intent.AddFlags(ActivityFlags.ReorderToFront);
|
||||
StartActivity(intent);
|
||||
}
|
||||
|
||||
await Task.Delay(1000);
|
||||
{
|
||||
Intent intent = new Intent(_activity1, typeof(Activity1));
|
||||
intent.AddFlags(ActivityFlags.ReorderToFront);
|
||||
_activity1.StartActivity(intent);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
this.Finish();
|
||||
_activity1.ReloadApplication();
|
||||
currentApplication.MainPage = new Issue10182.Issue10182SuccessPage();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public class Issue10182Test : ContentPage
|
||||
{
|
||||
public Issue10182Test()
|
||||
{
|
||||
Content = new StackLayout()
|
||||
{
|
||||
Children =
|
||||
{
|
||||
new Label()
|
||||
{
|
||||
Text = "Hold Please. Activity should vanish soon and you'll see a success label",
|
||||
AutomationId = "Loaded"
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public class Issue10182Application : Application
|
||||
{
|
||||
protected override void OnStart()
|
||||
{
|
||||
var contentPage = new Issue10182Test();
|
||||
base.OnStart();
|
||||
MainPage = contentPage;
|
||||
}
|
||||
|
||||
protected override void OnSleep()
|
||||
{
|
||||
base.OnSleep();
|
||||
MainPage = new NavigationPage(new ContentPage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
#if !FORMS_APPLICATION_ACTIVITY && !PRE_APPLICATION_CLASS
|
||||
|
||||
using Android.Content;
|
||||
using Xamarin.Forms.Controls.Issues;
|
||||
using System;
|
||||
|
||||
namespace Xamarin.Forms.ControlGallery.Android
|
||||
{
|
||||
public class MultiWindowService : IMultiWindowService
|
||||
{
|
||||
public void OpenWindow(Type type)
|
||||
{
|
||||
if (type == typeof(Issue10182))
|
||||
{
|
||||
var context = DependencyService.Resolve<Context>();
|
||||
Intent intent = new Intent(context, typeof(Issue10182Activity));
|
||||
context.StartActivity(intent);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -104,7 +104,9 @@
|
|||
<Compile Include="DisposeLabelRenderer.cs" />
|
||||
<Compile Include="DisposePageRenderer.cs" />
|
||||
<Compile Include="FormsAppCompatActivity.cs" />
|
||||
<Compile Include="Issue10182Activity.cs" />
|
||||
<Compile Include="MainApplication.cs" />
|
||||
<Compile Include="MultiWindowService.cs" />
|
||||
<Compile Include="PerformanceTrackerRenderer.cs" />
|
||||
<Compile Include="PlatformSpecificCoreGalleryFactory.cs" />
|
||||
<Compile Include="Resources\Resource.Designer.cs" />
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Text;
|
||||
using Xamarin.Forms.CustomAttributes;
|
||||
using Xamarin.Forms.Internals;
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading;
|
||||
|
||||
|
||||
#if UITEST
|
||||
using Xamarin.UITest;
|
||||
using NUnit.Framework;
|
||||
using Xamarin.Forms.Core.UITests;
|
||||
#endif
|
||||
|
||||
namespace Xamarin.Forms.Controls.Issues
|
||||
{
|
||||
[Preserve(AllMembers = true)]
|
||||
[Issue(IssueTracker.Github, 10182, "[Bug] Exception Ancestor must be provided for all pushes except first", PlatformAffected.Android, NavigationBehavior.SetApplicationRoot)]
|
||||
#if UITEST
|
||||
[NUnit.Framework.Category(Core.UITests.UITestCategories.Github10000)]
|
||||
[NUnit.Framework.Category(UITestCategories.LifeCycle)]
|
||||
#endif
|
||||
public class Issue10182 : TestContentPage
|
||||
{
|
||||
public Issue10182()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected override void Init()
|
||||
{
|
||||
Content = new StackLayout()
|
||||
{
|
||||
Children =
|
||||
{
|
||||
new Label()
|
||||
{
|
||||
Text = "Starting Activity to Test Changing Page on Resume. If success label shows up test has passed."
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#if !UITEST
|
||||
Device.BeginInvokeOnMainThread(() =>
|
||||
{
|
||||
DependencyService.Get<IMultiWindowService>().OpenWindow(this.GetType());
|
||||
});
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
public class Issue10182SuccessPage : ContentPage
|
||||
{
|
||||
public Issue10182SuccessPage()
|
||||
{
|
||||
Content = new StackLayout()
|
||||
{
|
||||
Children =
|
||||
{
|
||||
new Label()
|
||||
{
|
||||
Text = "Success.",
|
||||
AutomationId = "Success"
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#if UITEST && __ANDROID__
|
||||
[Test]
|
||||
public void AppDoesntCrashWhenResettingPage()
|
||||
{
|
||||
RunningApp.WaitForElement("Success");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
using Xamarin.Forms.CustomAttributes;
|
||||
using Xamarin.Forms.Internals;
|
||||
|
||||
namespace Xamarin.Forms.Controls.Issues
|
||||
{
|
||||
[Preserve(AllMembers = true)]
|
||||
[Issue(IssueTracker.Github, 10324, "Unable to intercept or disable mouse back button navigation on UWP", PlatformAffected.UWP)]
|
||||
public class Issue10324 : TestNavigationPage
|
||||
{
|
||||
protected override void Init()
|
||||
{
|
||||
Navigation.PushAsync(new IssueFirstPage());
|
||||
}
|
||||
|
||||
class IssueFirstPage : ContentPage
|
||||
{
|
||||
public IssueFirstPage()
|
||||
{
|
||||
Navigation.PushAsync(new IssueTestAlertPage());
|
||||
}
|
||||
}
|
||||
|
||||
class IssueTestAlertPage : ContentPage
|
||||
{
|
||||
public IssueTestAlertPage()
|
||||
{
|
||||
Title = "Hit Mouse BackButton/XButton1. An alert will appear (OnBackButtonPressed overridden)";
|
||||
Content = new StackLayout();
|
||||
|
||||
Navigation.PushAsync(new IssueTestBackPage());
|
||||
}
|
||||
|
||||
protected override bool OnBackButtonPressed()
|
||||
{
|
||||
DisplayAlert("OnBackButtonPressed", "OnBackButtonPressed", "OK");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class IssueTestBackPage : ContentPage
|
||||
{
|
||||
public IssueTestBackPage()
|
||||
{
|
||||
Title = "Hit Mouse BackButton/XButton1. Page will go back (OnBackButtonPressed not overridden)";
|
||||
Content = new StackLayout();
|
||||
}
|
||||
|
||||
protected override bool OnBackButtonPressed()
|
||||
{
|
||||
return base.OnBackButtonPressed();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
using Xamarin.Forms.CustomAttributes;
|
||||
using Xamarin.Forms.Internals;
|
||||
|
||||
#if UITEST
|
||||
using Xamarin.UITest;
|
||||
using NUnit.Framework;
|
||||
using Xamarin.Forms.Core.UITests;
|
||||
#endif
|
||||
|
||||
namespace Xamarin.Forms.Controls.Issues
|
||||
{
|
||||
#if UITEST
|
||||
[Category(UITestCategories.ScrollView)]
|
||||
#endif
|
||||
[Preserve(AllMembers = true)]
|
||||
[Issue(IssueTracker.Github, 11106,
|
||||
"[Bug] ScrollView UWP bug in 4.7.0.968!",
|
||||
PlatformAffected.UWP)]
|
||||
public class Issue11106 : TestContentPage
|
||||
{
|
||||
protected override void Init()
|
||||
{
|
||||
Title = "Issue 11106";
|
||||
|
||||
var grid = new Grid();
|
||||
|
||||
grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
|
||||
grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Star });
|
||||
|
||||
var instructions = new Label
|
||||
{
|
||||
Padding = 12,
|
||||
BackgroundColor = Color.Black,
|
||||
TextColor = Color.White,
|
||||
Text = "Scroll to the end and try to set focus to the last Entry. If you can tap the Entry and set the focus, the test has passed."
|
||||
};
|
||||
|
||||
var scroll = new ScrollView();
|
||||
|
||||
var layout = new StackLayout();
|
||||
|
||||
for (int i = 0; i < 30; i++)
|
||||
{
|
||||
layout.Children.Add(new Entry());
|
||||
}
|
||||
|
||||
scroll.Content = layout;
|
||||
|
||||
grid.Children.Add(instructions);
|
||||
Grid.SetRow(instructions, 0);
|
||||
|
||||
grid.Children.Add(scroll);
|
||||
Grid.SetRow(scroll, 1);
|
||||
|
||||
Content = grid;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,158 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Text;
|
||||
using Xamarin.Forms.CustomAttributes;
|
||||
using Xamarin.Forms.Internals;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
||||
#if UITEST
|
||||
using Xamarin.UITest;
|
||||
using NUnit.Framework;
|
||||
using Xamarin.Forms.Core.UITests;
|
||||
#endif
|
||||
|
||||
namespace Xamarin.Forms.Controls.Issues
|
||||
{
|
||||
[Preserve(AllMembers = true)]
|
||||
[Issue(IssueTracker.Github, 11107, "[Bug][iOS] Shell Navigation implicitly adds Tabbar",
|
||||
PlatformAffected.iOS)]
|
||||
#if UITEST
|
||||
[NUnit.Framework.Category(Core.UITests.UITestCategories.Github10000)]
|
||||
[NUnit.Framework.Category(UITestCategories.Shell)]
|
||||
#endif
|
||||
public class Issue11107 : TestShell
|
||||
{
|
||||
bool _tabBarIsVisible = false;
|
||||
Label _tabBarLabel;
|
||||
public Issue11107() : this(false)
|
||||
{
|
||||
}
|
||||
|
||||
public Issue11107(bool tabBarIsVisible)
|
||||
{
|
||||
_tabBarIsVisible = tabBarIsVisible;
|
||||
#if !UITEST
|
||||
Shell.SetTabBarIsVisible(this, _tabBarIsVisible);
|
||||
Shell.SetNavBarHasShadow(this, false);
|
||||
_tabBarLabel.Text = $"TabBarIsVisible: {_tabBarIsVisible}";
|
||||
#endif
|
||||
}
|
||||
|
||||
protected override void Init()
|
||||
{
|
||||
_tabBarLabel = new Label();
|
||||
ContentPage firstPage = new ContentPage()
|
||||
{
|
||||
Content = new StackLayout()
|
||||
{
|
||||
Children =
|
||||
{
|
||||
_tabBarLabel,
|
||||
new Label()
|
||||
{
|
||||
Text = "If this page has a tab bar the test has failed",
|
||||
AutomationId = "Page1Loaded"
|
||||
},
|
||||
new Button()
|
||||
{
|
||||
Text = "Run test again with TabBarIsVisible Toggled",
|
||||
Command = new Command(() =>
|
||||
{
|
||||
Application.Current.MainPage = new Issue11107(!Shell.GetTabBarIsVisible(this));
|
||||
}),
|
||||
AutomationId = "RunTestTabBarIsVisible"
|
||||
},
|
||||
new Button()
|
||||
{
|
||||
Text = "Run with Two Tabs and TabBarIsVisible False",
|
||||
Command = new Command(() =>
|
||||
{
|
||||
var shell = new Issue11107(false);
|
||||
shell.AddBottomTab("Second Tab");
|
||||
Application.Current.MainPage = shell;
|
||||
}),
|
||||
AutomationId = "RunTestTwoTabs"
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ContentPage secondPage = new ContentPage()
|
||||
{
|
||||
Content = new StackLayout()
|
||||
{
|
||||
Children =
|
||||
{
|
||||
new Label()
|
||||
{
|
||||
Text = "Hold Please!! Or fail the test if nothing happens."
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var item1 = AddFlyoutItem(firstPage, "Page1");
|
||||
item1.Items[0].Title = "Tab 1";
|
||||
item1.Items[0].AutomationId = "Tab1AutomationId";
|
||||
var item2 = AddFlyoutItem(secondPage, "Page2");
|
||||
|
||||
item1.Route = "FirstPage";
|
||||
Routing.RegisterRoute("Issue11107HeaderPage", typeof(Issue11107HeaderPage));
|
||||
|
||||
CurrentItem = item2;
|
||||
|
||||
Device.BeginInvokeOnMainThread(async () =>
|
||||
{
|
||||
await Task.Delay(1000);
|
||||
await GoToAsync("//FirstPage/Issue11107HeaderPage");
|
||||
});
|
||||
}
|
||||
|
||||
[Preserve(AllMembers = true)]
|
||||
public class Issue11107HeaderPage : ContentPage
|
||||
{
|
||||
public Issue11107HeaderPage()
|
||||
{
|
||||
Content = new StackLayout()
|
||||
{
|
||||
Children =
|
||||
{
|
||||
new Label()
|
||||
{
|
||||
Text = "If this page has a tab bar the test has failed",
|
||||
AutomationId = "SecondPageLoaded"
|
||||
},
|
||||
new Label()
|
||||
{
|
||||
Text = "Click the Back Button"
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if UITEST
|
||||
[Test]
|
||||
public void TabShouldntBeVisibleWhenThereIsOnlyOnePage()
|
||||
{
|
||||
RunTests();
|
||||
RunningApp.Tap("RunTestTabBarIsVisible");
|
||||
RunTests();
|
||||
RunningApp.Tap("RunTestTwoTabs");
|
||||
RunTests();
|
||||
|
||||
void RunTests()
|
||||
{
|
||||
RunningApp.WaitForElement("SecondPageLoaded");
|
||||
RunningApp.WaitForNoElement("Tab1AutomationId");
|
||||
TapBackArrow();
|
||||
RunningApp.WaitForElement("Page1Loaded");
|
||||
RunningApp.WaitForNoElement("Tab1AutomationId");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
|
@ -10,6 +10,7 @@
|
|||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)CollectionViewGroupTypeIssue.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Issue10324.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Github9536.xaml.cs">
|
||||
<DependentUpon>Github9536.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
|
@ -25,6 +26,7 @@
|
|||
</Compile>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Issue10744.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Issue10909.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Issue11106.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Issue8291.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Issue2674.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Issue6484.cs" />
|
||||
|
@ -1432,6 +1434,8 @@
|
|||
</Compile>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Issue11031.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Issue10940.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Issue10182.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Issue11107.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Bugzilla22229.xaml">
|
||||
|
@ -2147,4 +2151,4 @@
|
|||
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
using System;
|
||||
|
||||
|
||||
|
||||
namespace Xamarin.Forms.Controls.Issues
|
||||
{
|
||||
public interface IMultiWindowService
|
||||
{
|
||||
void OpenWindow(Type type);
|
||||
}
|
||||
}
|
|
@ -36,6 +36,15 @@ namespace Xamarin.Forms.Core.UnitTests
|
|||
return navPage;
|
||||
}
|
||||
|
||||
protected T GetVisiblePage<T>(Shell shell)
|
||||
where T : Page
|
||||
{
|
||||
if (shell?.CurrentItem?.CurrentItem is IShellSectionController scc)
|
||||
return (T)scc.PresentedPage;
|
||||
|
||||
return default(T);
|
||||
}
|
||||
|
||||
protected IEnumerable<Element> GetParentsPath(Element self)
|
||||
{
|
||||
Element current = self;
|
||||
|
@ -96,6 +105,9 @@ namespace Xamarin.Forms.Core.UnitTests
|
|||
protected override bool OnBackButtonPressed()
|
||||
{
|
||||
if (CancelNavigationOnBackButtonPressed == "true")
|
||||
return true;
|
||||
|
||||
if (CancelNavigationOnBackButtonPressed == "false")
|
||||
return false;
|
||||
|
||||
return base.OnBackButtonPressed();
|
||||
|
@ -260,10 +272,17 @@ namespace Xamarin.Forms.Core.UnitTests
|
|||
OnNavigatingCount++;
|
||||
}
|
||||
|
||||
public Func<bool> OnBackButtonPressedFunc;
|
||||
protected override bool OnBackButtonPressed()
|
||||
{
|
||||
var result = OnBackButtonPressedFunc?.Invoke() ?? false;
|
||||
|
||||
OnBackButtonPressedCount++;
|
||||
return base.OnBackButtonPressed();
|
||||
|
||||
if(!result)
|
||||
result = base.OnBackButtonPressed();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
|
|
|
@ -611,15 +611,43 @@ namespace Xamarin.Forms.Core.UnitTests
|
|||
Assume.That(shell.CurrentState.Location.ToString(), Is.EqualTo("//one/tabone/content"));
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public async Task OnBackbuttonPressedFiresOnPage()
|
||||
{
|
||||
Shell shell = new Shell();
|
||||
public async Task OnBackbuttonPressedPageReturnsTrue()
|
||||
{
|
||||
TestShell shell = new TestShell();
|
||||
|
||||
Routing.RegisterRoute("OnBackbuttonPressedFiresOnPage", typeof(ShellTestPage));
|
||||
shell.Items.Add(CreateShellItem());
|
||||
await shell.GoToAsync($"OnBackbuttonPressedFiresOnPage?CancelNavigationOnBackButtonPressed=true");
|
||||
Assert.AreEqual(false, shell.SendBackButtonPressed());
|
||||
|
||||
shell.SendBackButtonPressed();
|
||||
Assert.AreEqual(2, shell.Navigation.NavigationStack.Count);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task OnBackbuttonPressedPageReturnsFalse()
|
||||
{
|
||||
TestShell shell = new TestShell();
|
||||
|
||||
Routing.RegisterRoute("OnBackbuttonPressedFiresOnPage", typeof(ShellTestPage));
|
||||
shell.Items.Add(CreateShellItem());
|
||||
await shell.GoToAsync($"OnBackbuttonPressedFiresOnPage?CancelNavigationOnBackButtonPressed=false");
|
||||
|
||||
shell.SendBackButtonPressed();
|
||||
Assert.AreEqual(1, shell.Navigation.NavigationStack.Count);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task OnBackbuttonPressedShellReturnsTrue()
|
||||
{
|
||||
TestShell shell = new TestShell();
|
||||
|
||||
Routing.RegisterRoute("OnBackbuttonPressedShellReturnsTrue", typeof(ShellTestPage));
|
||||
shell.Items.Add(CreateShellItem());
|
||||
await shell.GoToAsync($"OnBackbuttonPressedShellReturnsTrue");
|
||||
shell.OnBackButtonPressedFunc = () => true;
|
||||
shell.SendBackButtonPressed();
|
||||
Assert.AreEqual(2, shell.Navigation.NavigationStack.Count);
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
|
|
@ -286,7 +286,7 @@ namespace Xamarin.Forms
|
|||
protected virtual bool OnBackButtonPressed()
|
||||
{
|
||||
if (RealParent is BaseShellItem || RealParent is Shell)
|
||||
return true;
|
||||
return false;
|
||||
|
||||
var application = RealParent as Application;
|
||||
if (application == null || this == application.MainPage)
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
using System;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace Xamarin.Forms.Shapes
|
||||
{
|
||||
|
@ -12,7 +11,6 @@ namespace Xamarin.Forms.Shapes
|
|||
}
|
||||
|
||||
[TypeConverter(typeof(MatrixTypeConverter))]
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public struct Matrix
|
||||
{
|
||||
internal double _m11;
|
||||
|
|
|
@ -1028,24 +1028,31 @@ namespace Xamarin.Forms
|
|||
|
||||
protected override bool OnBackButtonPressed()
|
||||
{
|
||||
if(GetVisiblePage() is Page page)
|
||||
{
|
||||
if(!page.SendBackButtonPressed())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (GetVisiblePage() is Page page && page.SendBackButtonPressed())
|
||||
return true;
|
||||
|
||||
var currentContent = CurrentItem?.CurrentItem;
|
||||
if (currentContent != null && currentContent.Stack.Count > 1)
|
||||
{
|
||||
currentContent.Navigation.PopAsync();
|
||||
NavigationPop();
|
||||
return true;
|
||||
}
|
||||
|
||||
var args = new ShellNavigatingEventArgs(this.CurrentState, "", ShellNavigationSource.Pop, true);
|
||||
OnNavigating(args);
|
||||
return args.Cancelled;
|
||||
|
||||
async void NavigationPop()
|
||||
{
|
||||
try
|
||||
{
|
||||
await currentContent.Navigation.PopAsync();
|
||||
}
|
||||
catch(Exception exc)
|
||||
{
|
||||
Internals.Log.Warning(nameof(Shell), $"Failed to Navigate Back: {exc}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ValidDefaultShellItem(Element child) => !(child is MenuShellItem);
|
||||
|
|
|
@ -400,7 +400,7 @@ namespace Xamarin.Forms.Platform.Android
|
|||
if (_needMainPageAssign)
|
||||
{
|
||||
_needMainPageAssign = false;
|
||||
|
||||
SettingMainPage();
|
||||
SetMainPage();
|
||||
}
|
||||
|
||||
|
|
|
@ -254,8 +254,11 @@ namespace Xamarin.Forms.Platform.Android.AppCompat
|
|||
|
||||
internal void SettingNewPage()
|
||||
{
|
||||
_previousNavModel = _navModel;
|
||||
_navModel = new NavigationModel();
|
||||
if (Page != null)
|
||||
{
|
||||
_previousNavModel = _navModel;
|
||||
_navModel = new NavigationModel();
|
||||
}
|
||||
}
|
||||
|
||||
internal void SetPage(Page newRoot)
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using NUnit.Framework;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Platform.UAP.UnitTests;
|
||||
using Xamarin.Forms.Platform.UWP;
|
||||
|
||||
[assembly: ExportRenderer(typeof(TestShell), typeof(TestShellRenderer))]
|
||||
namespace Xamarin.Forms.Platform.UAP.UnitTests
|
||||
{
|
||||
public class ShellTests : PlatformTestFixture
|
||||
{
|
||||
[Test, Category("Shell")]
|
||||
[Description("Shell doesn't crash when Flyout Behavior Initialized to Locked")]
|
||||
public async Task FlyoutHeaderReactsToChanges()
|
||||
{
|
||||
var shell = CreateShell();
|
||||
shell.FlyoutBehavior = FlyoutBehavior.Locked;
|
||||
|
||||
try
|
||||
{
|
||||
await Device.InvokeOnMainThreadAsync(() =>
|
||||
{
|
||||
var r = GetRenderer(shell);
|
||||
});
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
Assert.Fail(exc.ToString());
|
||||
}
|
||||
|
||||
Assert.Pass();
|
||||
}
|
||||
|
||||
Shell CreateShell()
|
||||
{
|
||||
return new Shell()
|
||||
{
|
||||
Items =
|
||||
{
|
||||
new FlyoutItem()
|
||||
{
|
||||
Items =
|
||||
{
|
||||
new Tab()
|
||||
{
|
||||
Items =
|
||||
{
|
||||
new ShellContent()
|
||||
{
|
||||
Content = new ContentPage()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public class TestShell : Shell { }
|
||||
|
||||
public class TestShellRenderer : ShellRenderer
|
||||
{
|
||||
}
|
||||
}
|
|
@ -131,6 +131,7 @@
|
|||
<Compile Include="RotationTests.cs" />
|
||||
<Compile Include="ScaleTests.cs" />
|
||||
<Compile Include="ScrollBarVisibilityTests.cs" />
|
||||
<Compile Include="ShellTests.cs" />
|
||||
<EmbeddedResource Include="Properties\Xamarin.Forms.Platform.UAP.UnitTests.rd.xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
|
|
@ -15,6 +15,9 @@ namespace Xamarin.Forms.Platform.UWP
|
|||
{
|
||||
bool _fontApplied;
|
||||
|
||||
FormsButton _button;
|
||||
PointerEventHandler _pointerPressedHandler;
|
||||
|
||||
protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
|
||||
{
|
||||
base.OnElementChanged(e);
|
||||
|
@ -23,13 +26,13 @@ namespace Xamarin.Forms.Platform.UWP
|
|||
{
|
||||
if (Control == null)
|
||||
{
|
||||
var button = new FormsButton();
|
||||
_button = new FormsButton();
|
||||
_pointerPressedHandler = new PointerEventHandler(OnPointerPressed);
|
||||
_button.Click += OnButtonClick;
|
||||
_button.AddHandler(PointerPressedEvent, _pointerPressedHandler, true);
|
||||
_button.Loaded += ButtonOnLoaded;
|
||||
|
||||
button.Click += OnButtonClick;
|
||||
button.AddHandler(PointerPressedEvent, new PointerEventHandler(OnPointerPressed), true);
|
||||
button.Loaded += ButtonOnLoaded;
|
||||
|
||||
SetNativeControl(button);
|
||||
SetNativeControl(_button);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -289,5 +292,24 @@ namespace Xamarin.Forms.Platform.UWP
|
|||
Element.Padding.Bottom
|
||||
);
|
||||
}
|
||||
|
||||
bool _isDisposed;
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (_isDisposed)
|
||||
return;
|
||||
if (_button != null)
|
||||
{
|
||||
_button.Click -= OnButtonClick;
|
||||
_button.RemoveHandler(PointerPressedEvent, _pointerPressedHandler);
|
||||
_button.Loaded -= ButtonOnLoaded;
|
||||
|
||||
_pointerPressedHandler = null;
|
||||
}
|
||||
|
||||
_isDisposed = true;
|
||||
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -328,9 +328,9 @@ namespace Xamarin.Forms.Platform.UWP
|
|||
}
|
||||
}
|
||||
|
||||
async void OnBackClicked(object sender, RoutedEventArgs e)
|
||||
void OnBackClicked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
await Element.PopAsync();
|
||||
Element?.SendBackButtonPressed();
|
||||
}
|
||||
|
||||
void OnChildrenChanged(object sender, NotifyCollectionChangedEventArgs e)
|
||||
|
|
|
@ -23,7 +23,7 @@ namespace Xamarin.Forms.Platform.UWP
|
|||
const string NavigationViewBackButton = "NavigationViewBackButton";
|
||||
internal const string ShellStyle = "ShellNavigationView";
|
||||
Shell _shell;
|
||||
|
||||
FlyoutBehavior _flyoutBehavior;
|
||||
ShellItemRenderer ItemRenderer { get; }
|
||||
|
||||
public ShellRenderer()
|
||||
|
@ -65,7 +65,9 @@ namespace Xamarin.Forms.Platform.UWP
|
|||
UpdatePaneButtonColor(NavigationViewBackButton, false);
|
||||
UpdateFlyoutBackgroundColor();
|
||||
UpdateFlyoutBackdropColor();
|
||||
ShellSplitView.UpdateFlyoutBackdropColor();
|
||||
|
||||
if(_flyoutBehavior == FlyoutBehavior.Flyout)
|
||||
ShellSplitView.UpdateFlyoutBackdropColor();
|
||||
}
|
||||
|
||||
void OnPaneClosed()
|
||||
|
@ -179,6 +181,9 @@ namespace Xamarin.Forms.Platform.UWP
|
|||
|
||||
protected virtual void UpdateFlyoutBackdropColor()
|
||||
{
|
||||
if (_flyoutBehavior != FlyoutBehavior.Flyout)
|
||||
return;
|
||||
|
||||
var splitView = ShellSplitView;
|
||||
if (splitView != null)
|
||||
{
|
||||
|
@ -295,9 +300,10 @@ namespace Xamarin.Forms.Platform.UWP
|
|||
}
|
||||
|
||||
#endregion IAppearanceObserver
|
||||
|
||||
|
||||
void IFlyoutBehaviorObserver.OnFlyoutBehaviorChanged(FlyoutBehavior behavior)
|
||||
{
|
||||
_flyoutBehavior = behavior;
|
||||
switch (behavior)
|
||||
{
|
||||
case FlyoutBehavior.Disabled:
|
||||
|
|
|
@ -24,6 +24,9 @@ namespace Xamarin.Forms.Platform.UWP
|
|||
{
|
||||
var dismissLayer = ((WRectangle)GetTemplateChild("LightDismissLayer"));
|
||||
|
||||
if (dismissLayer == null)
|
||||
return;
|
||||
|
||||
if (_defaultBrush == null)
|
||||
_defaultBrush = dismissLayer.Fill;
|
||||
|
||||
|
|
|
@ -5,6 +5,8 @@ namespace Xamarin.Forms.Platform.UWP
|
|||
{
|
||||
public class StepperRenderer : ViewRenderer<Stepper, StepperControl>, ITabStopOnDescendants
|
||||
{
|
||||
bool _isDisposed;
|
||||
|
||||
protected override void OnElementChanged(ElementChangedEventArgs<Stepper> e)
|
||||
{
|
||||
base.OnElementChanged(e);
|
||||
|
@ -80,5 +82,19 @@ namespace Xamarin.Forms.Platform.UWP
|
|||
{
|
||||
Control.Value = Element.Value;
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (_isDisposed)
|
||||
return;
|
||||
|
||||
if (disposing && Control != null)
|
||||
{
|
||||
Control.ValueChanged -= OnControlValue;
|
||||
}
|
||||
|
||||
_isDisposed = true;
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,6 +5,7 @@ using System.Collections.Specialized;
|
|||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Hosting;
|
||||
using Windows.UI.Xaml.Input;
|
||||
using Windows.UI.Xaml.Media;
|
||||
using Xamarin.Forms.Internals;
|
||||
|
@ -30,6 +31,8 @@ namespace Xamarin.Forms.Platform.UWP
|
|||
bool _wasPanGestureStartedSent;
|
||||
bool _wasPinchGestureStartedSent;
|
||||
|
||||
static bool HasClip;
|
||||
|
||||
public VisualElementTracker()
|
||||
{
|
||||
_collectionChangedHandler = ModelGestureRecognizersOnCollectionChanged;
|
||||
|
@ -522,14 +525,35 @@ namespace Xamarin.Forms.Platform.UWP
|
|||
|
||||
static void UpdateClip(VisualElement view, FrameworkElement frameworkElement)
|
||||
{
|
||||
if (!ShouldUpdateClip(view, frameworkElement))
|
||||
return;
|
||||
|
||||
var geometry = view.Clip;
|
||||
|
||||
HasClip = geometry != null;
|
||||
|
||||
if (CompositionHelper.IsCompositionGeometryTypePresent)
|
||||
frameworkElement.ClipVisual(geometry);
|
||||
else
|
||||
frameworkElement.Clip(geometry);
|
||||
}
|
||||
|
||||
|
||||
static bool ShouldUpdateClip(VisualElement view, FrameworkElement frameworkElement)
|
||||
{
|
||||
if (view == null || frameworkElement == null)
|
||||
return false;
|
||||
|
||||
var formsGeometry = view.Clip;
|
||||
|
||||
if (formsGeometry != null)
|
||||
return true;
|
||||
|
||||
if (formsGeometry == null && HasClip)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void UpdateOpacity(VisualElement view, FrameworkElement frameworkElement)
|
||||
{
|
||||
frameworkElement.Opacity = view.Opacity;
|
||||
|
|
|
@ -472,9 +472,12 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
{
|
||||
if (e.PropertyName == "HasContextActions")
|
||||
{
|
||||
var parentListView = _cell.RealParent as ListView;
|
||||
var recycling = parentListView != null &&
|
||||
if (_cell == null)
|
||||
return;
|
||||
|
||||
var recycling = _cell.RealParent is ListView parentListView &&
|
||||
((parentListView.CachingStrategy & ListViewCachingStrategy.RecycleElement) != 0);
|
||||
|
||||
if (!recycling)
|
||||
ReloadRow();
|
||||
}
|
||||
|
|
|
@ -368,6 +368,12 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
return null;
|
||||
}
|
||||
|
||||
public override void ViewWillLayoutSubviews()
|
||||
{
|
||||
UpdateTabBarHidden();
|
||||
base.ViewWillLayoutSubviews();
|
||||
}
|
||||
|
||||
void UpdateTabBarHidden()
|
||||
{
|
||||
if (ShellItemController == null)
|
||||
|
|
|
@ -9,6 +9,12 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
{
|
||||
public class EllipseRenderer : ShapeRenderer<Ellipse, EllipseView>
|
||||
{
|
||||
[Internals.Preserve(Conditional = true)]
|
||||
public EllipseRenderer()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected override void OnElementChanged(ElementChangedEventArgs<Ellipse> args)
|
||||
{
|
||||
if (Control == null)
|
||||
|
|
|
@ -11,6 +11,12 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
{
|
||||
public class LineRenderer : ShapeRenderer<Line, LineView>
|
||||
{
|
||||
[Internals.Preserve(Conditional = true)]
|
||||
public LineRenderer()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected override void OnElementChanged(ElementChangedEventArgs<Line> args)
|
||||
{
|
||||
if (Control == null)
|
||||
|
|
|
@ -10,6 +10,12 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
{
|
||||
public class PathRenderer : ShapeRenderer<Path, PathView>
|
||||
{
|
||||
[Internals.Preserve(Conditional = true)]
|
||||
public PathRenderer()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected override void OnElementChanged(ElementChangedEventArgs<Path> args)
|
||||
{
|
||||
if (Control == null)
|
||||
|
|
|
@ -10,6 +10,12 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
{
|
||||
public class PolygonRenderer : ShapeRenderer<Polygon, PolygonView>
|
||||
{
|
||||
[Internals.Preserve(Conditional = true)]
|
||||
public PolygonRenderer()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected override void OnElementChanged(ElementChangedEventArgs<Polygon> args)
|
||||
{
|
||||
if (Control == null)
|
||||
|
|
|
@ -10,6 +10,12 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
{
|
||||
public class PolylineRenderer : ShapeRenderer<Polyline, PolylineView>
|
||||
{
|
||||
[Internals.Preserve(Conditional = true)]
|
||||
public PolylineRenderer()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected override void OnElementChanged(ElementChangedEventArgs<Polyline> args)
|
||||
{
|
||||
if (Control == null)
|
||||
|
|
|
@ -11,6 +11,12 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
{
|
||||
public class RectangleRenderer : ShapeRenderer<Rect, RectView>
|
||||
{
|
||||
[Internals.Preserve(Conditional = true)]
|
||||
public RectangleRenderer()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected override void OnElementChanged(ElementChangedEventArgs<Rect> args)
|
||||
{
|
||||
if (Control == null)
|
||||
|
|
Загрузка…
Ссылка в новой задаче