From 487b669aaf42388e37cc768dc0b4937981bdf6f1 Mon Sep 17 00:00:00 2001 From: Jason Smith Date: Mon, 11 Jun 2018 02:54:00 -0700 Subject: [PATCH 1/6] Make sure PlatformConfiguration created with Stepper (#2994) --- Xamarin.Forms.Core/Stepper.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Xamarin.Forms.Core/Stepper.cs b/Xamarin.Forms.Core/Stepper.cs index 67f4b8eb5..6aa4ca463 100644 --- a/Xamarin.Forms.Core/Stepper.cs +++ b/Xamarin.Forms.Core/Stepper.cs @@ -50,7 +50,7 @@ namespace Xamarin.Forms _platformConfigurationRegistry = new Lazy>(() => new PlatformConfigurationRegistry(this)); } - public Stepper(double min, double max, double val, double increment) + public Stepper(double min, double max, double val, double increment) : this() { if (min >= max) throw new ArgumentOutOfRangeException("min"); From 44182014ade679ab01492701d5e2e3d10f2fbfd3 Mon Sep 17 00:00:00 2001 From: Stephane Delcroix Date: Mon, 11 Jun 2018 11:56:17 +0200 Subject: [PATCH 2/6] CSSG Incremental (#2940) * CSSG Incremental * [tests] MSBuild integration tests for CssG --- .nuspec/Xamarin.Forms.targets | 28 +++++++++------ Xamarin.Forms.Build.Tasks/CssGTask.cs | 34 ++++++++++-------- Xamarin.Forms.Build.Tasks/GetTasksAbi.cs | 2 +- .../MSBuild/MSBuildTests.cs | 36 +++++++++++++++++-- 4 files changed, 72 insertions(+), 28 deletions(-) diff --git a/.nuspec/Xamarin.Forms.targets b/.nuspec/Xamarin.Forms.targets index 33edf05da..07722de87 100644 --- a/.nuspec/Xamarin.Forms.targets +++ b/.nuspec/Xamarin.Forms.targets @@ -38,7 +38,7 @@ - <_XFTasksExpectedAbi>4 + <_XFTasksExpectedAbi>5 - - - <_CssGAlreadyExecuted>true - + + + + <_CSSInputs Include="@(EmbeddedResource)" Condition="'%(Extension)' == '.css' AND '$(DefaultLanguageSourceExtension)' == '.cs' AND '%(TargetPath)' != ''" /> + <_CSSOutputs Include="@(_CSSInputs->'$(IntermediateOutputPath)%(TargetPath).g.cs')" /> + + + + - - - + AssemblyName = "$(AssemblyName)" /> + + + + diff --git a/Xamarin.Forms.Build.Tasks/CssGTask.cs b/Xamarin.Forms.Build.Tasks/CssGTask.cs index b74fb8321..2299f9cfb 100644 --- a/Xamarin.Forms.Build.Tasks/CssGTask.cs +++ b/Xamarin.Forms.Build.Tasks/CssGTask.cs @@ -10,41 +10,47 @@ namespace Xamarin.Forms.Build.Tasks { public class CssGTask : Task { - readonly List _generatedCodeFiles = new List(); + [Required] + public ITaskItem[] CSSFiles { get; set; } [Required] - public ITaskItem[] XamlFiles { get; set; } - - [Output] - public ITaskItem[] GeneratedCodeFiles => _generatedCodeFiles.ToArray(); + public ITaskItem[] OutputFiles { get; set; } public string Language { get; set; } public string AssemblyName { get; set; } - public string OutputPath { get; set; } public override bool Execute() { bool success = true; Log.LogMessage(MessageImportance.Normal, "Generating assembly attributes for CSS files"); - if (XamlFiles == null) { + if (CSSFiles == null || OutputFiles == null) { Log.LogMessage(MessageImportance.Low, "Skipping CssG"); return true; } - foreach (var xamlFile in XamlFiles) { - var outputFile = Path.Combine(OutputPath, $"{xamlFile.GetMetadata("TargetPath")}.g.cs"); - var generator = new CssGenerator(xamlFile, Language, AssemblyName, outputFile, Log); + if (CSSFiles.Length != OutputFiles.Length) { + Log.LogError("\"{2}\" refers to {0} item(s), and \"{3}\" refers to {1} item(s). They must have the same number of items.", CSSFiles.Length, OutputFiles.Length, "CSSFiles", "OutputFiles"); + return false; + } + + for (var i = 0; i < CSSFiles.Length;i++) { + var cssFile = CSSFiles[i]; + var outputFile = OutputFiles[i].ItemSpec; + + var generator = new CssGenerator(cssFile, Language, AssemblyName, outputFile, Log); try { - if (generator.Execute()) - _generatedCodeFiles.Add(new TaskItem(Microsoft.Build.Evaluation.ProjectCollection.Escape(outputFile))); + if (!generator.Execute()) { + //If Execute() fails, the file still needs to exist because it is added to the ItemGroup + File.WriteAllText(outputFile, string.Empty); + } } catch (XmlException xe) { - Log.LogError(null, null, null, xamlFile.ItemSpec, xe.LineNumber, xe.LinePosition, 0, 0, xe.Message, xe.HelpLink, xe.Source); + Log.LogError(null, null, null, cssFile.ItemSpec, xe.LineNumber, xe.LinePosition, 0, 0, xe.Message, xe.HelpLink, xe.Source); success = false; } catch (Exception e) { - Log.LogError(null, null, null, xamlFile.ItemSpec, 0, 0, 0, 0, e.Message, e.HelpLink, e.Source); + Log.LogError(null, null, null, cssFile.ItemSpec, 0, 0, 0, 0, e.Message, e.HelpLink, e.Source); success = false; } } diff --git a/Xamarin.Forms.Build.Tasks/GetTasksAbi.cs b/Xamarin.Forms.Build.Tasks/GetTasksAbi.cs index ea7d14162..80c87266f 100644 --- a/Xamarin.Forms.Build.Tasks/GetTasksAbi.cs +++ b/Xamarin.Forms.Build.Tasks/GetTasksAbi.cs @@ -6,7 +6,7 @@ namespace Xamarin.Forms.Build.Tasks public class GetTasksAbi : Task { [Output] - public string AbiVersion { get; } = "4"; + public string AbiVersion { get; } = "5"; public override bool Execute() => true; diff --git a/Xamarin.Forms.Xaml.UnitTests/MSBuild/MSBuildTests.cs b/Xamarin.Forms.Xaml.UnitTests/MSBuild/MSBuildTests.cs index 568f0c9b4..0a884583a 100644 --- a/Xamarin.Forms.Xaml.UnitTests/MSBuild/MSBuildTests.cs +++ b/Xamarin.Forms.Xaml.UnitTests/MSBuild/MSBuildTests.cs @@ -45,6 +45,15 @@ namespace Xamarin.Forms.Xaml.UnitTests "; } + class Css + { + public const string Foo = @" + label { + color: azure; + background-color: aliceblue; + }"; + } + string testDirectory; string tempDirectory; string intermediateDirectory; @@ -139,6 +148,9 @@ namespace Xamarin.Forms.Xaml.UnitTests //Let's enable XamlC assembly-wide project.Add (AddFile ("AssemblyInfo.cs", "Compile", "[assembly: Xamarin.Forms.Xaml.XamlCompilation (Xamarin.Forms.Xaml.XamlCompilationOptions.Compile)]")); + //Add a single CSS file + project.Add (AddFile ("Foo.css", "EmbeddedResource", Css.Foo)); + if (!sdkStyle) project.Add (NewElement ("Import").WithAttribute ("Project", @"$(MSBuildBinPath)\Microsoft.CSharp.targets")); @@ -229,6 +241,7 @@ namespace Xamarin.Forms.Xaml.UnitTests AssertExists (Path.Combine (intermediateDirectory, "test.dll"), nonEmpty: true); AssertExists (Path.Combine (intermediateDirectory, "MainPage.xaml.g.cs"), nonEmpty: true); + AssertExists (Path.Combine (intermediateDirectory, "Foo.css.g.cs"), nonEmpty: true); AssertExists (Path.Combine (intermediateDirectory, "XamlC.stamp")); } @@ -246,11 +259,14 @@ namespace Xamarin.Forms.Xaml.UnitTests Build (projectFile); var mainPageXamlG = Path.Combine (intermediateDirectory, "MainPage.xaml.g.cs"); + var fooCssG = Path.Combine (intermediateDirectory, "Foo.css.g.cs"); var xamlCStamp = Path.Combine (intermediateDirectory, "XamlC.stamp"); AssertExists (mainPageXamlG, nonEmpty: true); + AssertExists (fooCssG, nonEmpty: true); AssertExists (xamlCStamp); var expectedXamlG = new FileInfo (mainPageXamlG).LastWriteTimeUtc; + var expectdCssG = new FileInfo (fooCssG).LastWriteTimeUtc; var expectedXamlC = new FileInfo (xamlCStamp).LastWriteTimeUtc; //Build again @@ -259,8 +275,10 @@ namespace Xamarin.Forms.Xaml.UnitTests AssertExists (xamlCStamp); var actualXamlG = new FileInfo (mainPageXamlG).LastWriteTimeUtc; + var actualCssG = new FileInfo (fooCssG).LastWriteTimeUtc; var actualXamlC = new FileInfo (xamlCStamp).LastWriteTimeUtc; Assert.AreEqual (expectedXamlG, actualXamlG, $"Timestamps should match for {mainPageXamlG}."); + Assert.AreEqual (expectdCssG, actualCssG, $"Timestamps should match for {fooCssG}."); Assert.AreEqual (expectedXamlC, actualXamlC, $"Timestamps should match for {xamlCStamp}."); } @@ -278,13 +296,16 @@ namespace Xamarin.Forms.Xaml.UnitTests Build (projectFile); var mainPageXamlG = Path.Combine (intermediateDirectory, "MainPage.xaml.g.cs"); + var fooCssG = Path.Combine (intermediateDirectory, "Foo.css.g.cs"); var xamlCStamp = Path.Combine (intermediateDirectory, "XamlC.stamp"); AssertExists (mainPageXamlG, nonEmpty: true); + AssertExists (fooCssG, nonEmpty: true); AssertExists (xamlCStamp); //Clean Build (projectFile, "Clean"); AssertDoesNotExist (mainPageXamlG); + AssertDoesNotExist (fooCssG); AssertDoesNotExist (xamlCStamp); } @@ -328,25 +349,31 @@ namespace Xamarin.Forms.Xaml.UnitTests var assembly = Path.Combine (intermediateDirectory, "test.dll"); var mainPageXamlG = Path.Combine (intermediateDirectory, "Pages", "MainPage.xaml.g.cs"); + var fooCssG = Path.Combine (intermediateDirectory, "Foo.css.g.cs"); var xamlCStamp = Path.Combine (intermediateDirectory, "XamlC.stamp"); //The assembly should not be compiled AssertDoesNotExist (assembly); AssertExists (mainPageXamlG, nonEmpty: true); + AssertExists (fooCssG, nonEmpty: true); AssertExists (xamlCStamp); var expectedXamlG = new FileInfo (mainPageXamlG).LastWriteTimeUtc; + var expectedCssG = new FileInfo (fooCssG).LastWriteTimeUtc; var expectedXamlC = new FileInfo (xamlCStamp).LastWriteTimeUtc; //Build again, a full build Build (projectFile); AssertExists (assembly, nonEmpty: true); AssertExists (mainPageXamlG, nonEmpty: true); + AssertExists (fooCssG, nonEmpty: true); AssertExists (xamlCStamp); var actualXamlG = new FileInfo (mainPageXamlG).LastWriteTimeUtc; + var actualCssG = new FileInfo (fooCssG).LastWriteTimeUtc; var actualXamlC = new FileInfo (xamlCStamp).LastWriteTimeUtc; Assert.AreEqual (expectedXamlG, actualXamlG, $"Timestamps should match for {mainPageXamlG}."); + Assert.AreEqual (expectedCssG, actualCssG, $"Timestamps should match for {fooCssG}."); Assert.AreNotEqual (expectedXamlC, actualXamlC, $"Timestamps should *not* match for {xamlCStamp}."); } @@ -362,6 +389,7 @@ namespace Xamarin.Forms.Xaml.UnitTests Build (projectFile, "UpdateDesignTimeXaml"); AssertExists (Path.Combine (intermediateDirectory, "Pages", "MainPage.xaml.g.cs"), nonEmpty: true); + AssertDoesNotExist (Path.Combine (intermediateDirectory, "Foo.css.g.cs")); AssertDoesNotExist (Path.Combine (intermediateDirectory, "XamlC.stamp")); } @@ -377,14 +405,16 @@ namespace Xamarin.Forms.Xaml.UnitTests var mainPageXamlG = Path.Combine (intermediateDirectory, "MainPage.xaml.g.cs"); var customViewXamlG = Path.Combine (intermediateDirectory, "CustomView.xaml.g.cs"); + var fooCssG = Path.Combine (intermediateDirectory, "Foo.css.g.cs"); var xamlCStamp = Path.Combine (intermediateDirectory, "XamlC.stamp"); AssertExists (mainPageXamlG, nonEmpty: true); AssertExists (xamlCStamp); var expectedXamlG = new FileInfo (mainPageXamlG).LastWriteTimeUtc; + var expectedCssG = new FileInfo (fooCssG).LastWriteTimeUtc; var expectedXamlC = new FileInfo (xamlCStamp).LastWriteTimeUtc; - //Build again, after adding a file, this triggers a full XamlG and XamlC + //Build again, after adding a file, this triggers a full XamlG and XamlC -- *not* CssG project.Add (AddFile ("CustomView.xaml", "EmbeddedResource", Xaml.CustomView)); project.Save (projectFile); Build (projectFile); @@ -393,10 +423,12 @@ namespace Xamarin.Forms.Xaml.UnitTests AssertExists (xamlCStamp); var actualXamlG = new FileInfo (mainPageXamlG).LastWriteTimeUtc; + var actualCssG = new FileInfo (fooCssG).LastWriteTimeUtc; var actualXamlC = new FileInfo (xamlCStamp).LastWriteTimeUtc; var actualNewFile = new FileInfo (customViewXamlG).LastAccessTimeUtc; Assert.AreNotEqual (expectedXamlG, actualXamlG, $"Timestamps should *not* match for {mainPageXamlG}."); - Assert.AreNotEqual (expectedXamlG, actualNewFile, $"Timestamps should *not* match for {actualNewFile}."); + Assert.AreNotEqual (expectedXamlG, actualNewFile, $"Timestamps should *not* match for {customViewXamlG}."); + Assert.AreEqual (expectedCssG, actualCssG, $"Timestamps should match for {fooCssG}."); Assert.AreNotEqual (expectedXamlC, actualXamlC, $"Timestamps should *not* match for {xamlCStamp}."); } From 4bc56b4effe9e3d3927d40681980e326b34801c9 Mon Sep 17 00:00:00 2001 From: Jason Smith Date: Mon, 11 Jun 2018 04:00:32 -0700 Subject: [PATCH 3/6] Make sure stepper buttons are always the same size (#2995) fixes #2919 --- Xamarin.Forms.Platform.Android/Renderers/StepperRenderer.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Xamarin.Forms.Platform.Android/Renderers/StepperRenderer.cs b/Xamarin.Forms.Platform.Android/Renderers/StepperRenderer.cs index 40ebdebec..a9668ba14 100644 --- a/Xamarin.Forms.Platform.Android/Renderers/StepperRenderer.cs +++ b/Xamarin.Forms.Platform.Android/Renderers/StepperRenderer.cs @@ -36,6 +36,7 @@ namespace Xamarin.Forms.Platform.Android if (e.OldElement == null) { _downButton = new AButton(Context) { Text = "-", Gravity = GravityFlags.Center, Tag = this }; + _downButton.SetHeight((int)Context.ToPixels(10.0)); _downButton.SetOnClickListener(StepperListener.Instance); From f493397ea9af06d77f3794aa34e33a05afcfb599 Mon Sep 17 00:00:00 2001 From: Stephane Delcroix Date: Tue, 12 Jun 2018 13:33:37 +0200 Subject: [PATCH 4/6] [Core] Fixes setting to Null Binding Context in Picker (#3014) - fixes #2499 - fixes #2815 - closes #2833 --- .../Issue2499.cs | 49 +++++++++++++++++++ ...rin.Forms.Controls.Issues.Shared.projitems | 3 +- .../WindowsTestBase.cs | 2 +- Xamarin.Forms.Core/Picker.cs | 19 ++++--- 4 files changed, 63 insertions(+), 10 deletions(-) create mode 100644 Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue2499.cs diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue2499.cs b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue2499.cs new file mode 100644 index 000000000..532ccf370 --- /dev/null +++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue2499.cs @@ -0,0 +1,49 @@ +using System.Collections.Generic; +using Xamarin.Forms.CustomAttributes; +using Xamarin.Forms.Internals; + +#if UITEST +using Xamarin.UITest; +using Xamarin.UITest.Queries; +using NUnit.Framework; +#endif + +namespace Xamarin.Forms.Controls.Issues +{ + [Preserve(AllMembers = true)] + [Issue(IssueTracker.Github, 2499, "Binding Context set to Null in Picker", PlatformAffected.All)] + public class Issue2499 : TestContentPage + { + protected override void Init() + { + var _picker = new Picker() + { + ItemsSource = new List { "cat", "mouse", "rabbit" }, + AutomationId = "picker", + }; + _picker.SelectedIndexChanged += (_, __) => _picker.ItemsSource = null; + + Content = new StackLayout() + { + Children = + { + _picker + } + }; + } + +#if UITEST + [Test] + public void Issue2499Test () + { + RunningApp.Tap ("picker"); + AppResult[] items = RunningApp.Query("cat"); + Assert.AreNotEqual(items.Length, 0); + + RunningApp.Tap ("cat"); + items = RunningApp.Query("cat"); + Assert.AreEqual(items.Length, 0); + } +#endif + } +} \ No newline at end of file diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems index 66bce43e8..8147b62dd 100644 --- a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems +++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems @@ -241,6 +241,7 @@ + @@ -906,4 +907,4 @@ MSBuild:UpdateDesignTimeXaml - \ No newline at end of file + diff --git a/Xamarin.Forms.Core.Windows.UITests/WindowsTestBase.cs b/Xamarin.Forms.Core.Windows.UITests/WindowsTestBase.cs index 72d4cbafe..38f8947b2 100644 --- a/Xamarin.Forms.Core.Windows.UITests/WindowsTestBase.cs +++ b/Xamarin.Forms.Core.Windows.UITests/WindowsTestBase.cs @@ -23,7 +23,7 @@ namespace Xamarin.Forms.Core.UITests if (Session == null) { DesiredCapabilities appCapabilities = new DesiredCapabilities(); - appCapabilities.SetCapability("app", "0d4424f6-1e29-4476-ac00-ba22c3789cb6_wzjw7qdpbr1br!App"); + appCapabilities.SetCapability("app", "0d4424f6-1e29-4476-ac00-ba22c3789cb6_ph1m9x8skttmg!App"); appCapabilities.SetCapability("deviceName", "WindowsPC"); Session = new WindowsDriver(new Uri(WindowsApplicationDriverUrl), appCapabilities); Assert.IsNotNull(Session); diff --git a/Xamarin.Forms.Core/Picker.cs b/Xamarin.Forms.Core/Picker.cs index 865515471..b58a7ddf8 100644 --- a/Xamarin.Forms.Core/Picker.cs +++ b/Xamarin.Forms.Core/Picker.cs @@ -150,8 +150,11 @@ namespace Xamarin.Forms void OnItemsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { - SelectedIndex = SelectedIndex.Clamp(-1, Items.Count - 1); - UpdateSelectedItem(); + var oldIndex = SelectedIndex; + var newIndex = SelectedIndex = SelectedIndex.Clamp(-1, Items.Count - 1); + // If the index has not changed, still need to change the selected item + if (newIndex == oldIndex) + UpdateSelectedItem(newIndex); } static void OnItemsSourceChanged(BindableObject bindable, object oldValue, object newValue) @@ -214,13 +217,13 @@ namespace Xamarin.Forms ((LockableObservableListWrapper)Items).InternalClear(); foreach (object item in ItemsSource) ((LockableObservableListWrapper)Items).InternalAdd(GetDisplayMember(item)); - UpdateSelectedItem(); + UpdateSelectedItem(SelectedIndex); } static void OnSelectedIndexChanged(object bindable, object oldValue, object newValue) { var picker = (Picker)bindable; - picker.UpdateSelectedItem(); + picker.UpdateSelectedItem(picker.SelectedIndex); picker.SelectedIndexChanged?.Invoke(bindable, EventArgs.Empty); } @@ -239,19 +242,19 @@ namespace Xamarin.Forms SelectedIndex = Items.IndexOf(selectedItem); } - void UpdateSelectedItem() + void UpdateSelectedItem(int index) { - if (SelectedIndex == -1) { + if (index == -1) { SelectedItem = null; return; } if (ItemsSource != null) { - SelectedItem = ItemsSource [SelectedIndex]; + SelectedItem = ItemsSource [index]; return; } - SelectedItem = Items [SelectedIndex]; + SelectedItem = Items [index]; } public IPlatformElementConfiguration On() where T : IConfigPlatform From c512ce3eadde7d236c226e8952b8dbc384aee7c5 Mon Sep 17 00:00:00 2001 From: "E.Z. Hart" Date: Thu, 14 Jun 2018 07:46:55 -0600 Subject: [PATCH 5/6] [Android] Make ScrollViewRenderer handle double disposal; fixes #1931 , fixes #2011 (#3025) --- .../Issue1931.cs | 109 ++++++++++++++++++ ...rin.Forms.Controls.Issues.Shared.projitems | 3 +- .../Renderers/ScrollViewRenderer.cs | 15 ++- 3 files changed, 122 insertions(+), 5 deletions(-) create mode 100644 Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue1931.cs diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue1931.cs b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue1931.cs new file mode 100644 index 000000000..b9d6e0117 --- /dev/null +++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue1931.cs @@ -0,0 +1,109 @@ +using System.Collections.Generic; +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)] + [Category(UITestCategories.ListView)] +#endif + + [Preserve(AllMembers = true)] + [Issue(IssueTracker.Github, 1931, + "Xamarin Forms on Android: ScrollView on ListView header crashes app when closing page", + PlatformAffected.Android)] + public class Issue1931 : TestNavigationPage + { + const string Go = "Go"; + const string Back = "Back"; + const string Success = "Success"; + Label _result; + Label _instructions2; + + ContentPage RootPage() + { + var page = new ContentPage(); + page.Title = "GH1931 Root"; + + var button = new Button { Text = Go }; + button.Clicked += (sender, args) => PushAsync(ListViewPage()); + + var instructions = new Label { Text = $"Tap the {Go} button" }; + + _result = new Label { Text = Success, IsVisible = false }; + _instructions2 = new Label { Text = "If you can see this, the test has passed", IsVisible = false }; + + var layout = new StackLayout(); + layout.Children.Add(instructions); + layout.Children.Add(button); + layout.Children.Add(_result); + layout.Children.Add(_instructions2); + page.Content = layout; + + return page; + } + + ContentPage ListViewPage() + { + var page = new ContentPage(); + + var layout = new StackLayout(); + + var listView = new ListView(); + + var scrollView = new ScrollView { Content = new BoxView { Color = Color.Green } }; + + listView.Header = scrollView; + + listView.ItemsSource = new List { "One", "Two", "Three" }; + + page.Title = "GH1931 Test"; + + var instructions = new Label { Text = $"Tap the {Back} button" }; + + var button = new Button { Text = Back }; + button.Clicked += (sender, args) => PopAsync(); + + layout.Children.Add(instructions); + layout.Children.Add(button); + layout.Children.Add(listView); + + page.Content = layout; + + page.Appearing += (sender, args) => + { + _instructions2.IsVisible = true; + _result.IsVisible = true; + }; + + return page; + } + + protected override void Init() + { + PushAsync(RootPage()); + } + + +#if UITEST + [Test] + public void ScrollViewInHeaderDisposesProperly() + { + RunningApp.WaitForElement(Go); + RunningApp.Tap(Go); + + RunningApp.WaitForElement(Back); + RunningApp.Tap(Back); + + RunningApp.WaitForElement(Success); + } +#endif + } +} \ No newline at end of file diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems index 8147b62dd..4d4c1bc79 100644 --- a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems +++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems @@ -240,6 +240,7 @@ + @@ -907,4 +908,4 @@ MSBuild:UpdateDesignTimeXaml - + \ No newline at end of file diff --git a/Xamarin.Forms.Platform.Android/Renderers/ScrollViewRenderer.cs b/Xamarin.Forms.Platform.Android/Renderers/ScrollViewRenderer.cs index 4770fc542..6984a504f 100644 --- a/Xamarin.Forms.Platform.Android/Renderers/ScrollViewRenderer.cs +++ b/Xamarin.Forms.Platform.Android/Renderers/ScrollViewRenderer.cs @@ -24,6 +24,7 @@ namespace Xamarin.Forms.Platform.Android ScrollView _view; int _previousBottom; bool _isEnabled; + bool _disposed; public ScrollViewRenderer(Context context) : base(context) { @@ -176,18 +177,24 @@ namespace Xamarin.Forms.Platform.Android protected override void Dispose(bool disposing) { - base.Dispose(disposing); + if (_disposed) + { + return; + } - SetElement(null); + _disposed = true; if (disposing) { - Tracker.Dispose(); + SetElement(null); + Tracker?.Dispose(); Tracker = null; RemoveAllViews(); - _container.Dispose(); + _container?.Dispose(); _container = null; } + + base.Dispose(disposing); } protected override void OnAttachedToWindow() From 5a36e0aac62f7835400c40aac32feb8a6b742c6f Mon Sep 17 00:00:00 2001 From: Shane Neuville Date: Thu, 14 Jun 2018 12:49:53 -0600 Subject: [PATCH 6/6] Give XFCorePostProcessor a different GUID than Xamarin.Forms.Xaml.Design (#3041) --- Xamarin.Forms.sln | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/Xamarin.Forms.sln b/Xamarin.Forms.sln index 76befacc5..a4b27d11d 100644 --- a/Xamarin.Forms.sln +++ b/Xamarin.Forms.sln @@ -174,7 +174,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Xamarin.Forms.Maps.Design", EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Xamarin.Forms.Xaml.Design", "Xamarin.Forms.Xaml.Design\Xamarin.Forms.Xaml.Design.csproj", "{65BC4888-CC59-428A-9B75-540CF1C09480}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XFCorePostProcessor.Tasks", "XFCorePostProcessor.Tasks\XFCorePostProcessor.Tasks.csproj", "{5BBF4A3F-4AD1-47FD-B250-05EA793F939D}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "XFCorePostProcessor.Tasks", "XFCorePostProcessor.Tasks\XFCorePostProcessor.Tasks.csproj", "{5BBF4A3F-4AD1-47FD-B250-05EA793F939D}" EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution @@ -187,7 +187,6 @@ Global Xamarin.Forms.Core.UITests.Shared\Xamarin.Forms.Core.UITests.projitems*{a34ebe01-25bf-4e69-a2dc-2288dc625541}*SharedItemsImports = 4 Xamarin.Flex\Xamarin.Flex.projitems*{a6703c7d-d362-452a-a7a5-73771194d38c}*SharedItemsImports = 13 Xamarin.Forms.Controls.Issues\Xamarin.Forms.Controls.Issues.Shared\Xamarin.Forms.Controls.Issues.Shared.projitems*{cb9c96ce-125c-4a68-b6a1-c3ff1fbf93e1}*SharedItemsImports = 4 - docs\APIDocs.projitems*{dc1f3933-ac99-4887-8b09-e13c2b346d4f}*SharedItemsImports = 13 Xamarin.Forms.Core.UITests.Shared\Xamarin.Forms.Core.UITests.projitems*{e175485b-3c8c-47d7-8dd5-f7fed627eb25}*SharedItemsImports = 13 Xamarin.Forms.Controls.Issues\Xamarin.Forms.Controls.Issues.Shared\Xamarin.Forms.Controls.Issues.Shared.projitems*{eadd8100-b3ae-4a31-92c4-267a64a1c6eb}*SharedItemsImports = 4 Xamarin.Forms.Core.UITests.Shared\Xamarin.Forms.Core.UITests.projitems*{eadd8100-b3ae-4a31-92c4-267a64a1c6eb}*SharedItemsImports = 4 @@ -1575,6 +1574,18 @@ Global {65BC4888-CC59-428A-9B75-540CF1C09480}.Release|x64.Build.0 = Release|Any CPU {65BC4888-CC59-428A-9B75-540CF1C09480}.Release|x86.ActiveCfg = Release|Any CPU {65BC4888-CC59-428A-9B75-540CF1C09480}.Release|x86.Build.0 = Release|Any CPU + {5BBF4A3F-4AD1-47FD-B250-05EA793F939D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5BBF4A3F-4AD1-47FD-B250-05EA793F939D}.Debug|ARM.ActiveCfg = Debug|Any CPU + {5BBF4A3F-4AD1-47FD-B250-05EA793F939D}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {5BBF4A3F-4AD1-47FD-B250-05EA793F939D}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {5BBF4A3F-4AD1-47FD-B250-05EA793F939D}.Debug|x64.ActiveCfg = Debug|Any CPU + {5BBF4A3F-4AD1-47FD-B250-05EA793F939D}.Debug|x86.ActiveCfg = Debug|Any CPU + {5BBF4A3F-4AD1-47FD-B250-05EA793F939D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5BBF4A3F-4AD1-47FD-B250-05EA793F939D}.Release|ARM.ActiveCfg = Release|Any CPU + {5BBF4A3F-4AD1-47FD-B250-05EA793F939D}.Release|iPhone.ActiveCfg = Release|Any CPU + {5BBF4A3F-4AD1-47FD-B250-05EA793F939D}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {5BBF4A3F-4AD1-47FD-B250-05EA793F939D}.Release|x64.ActiveCfg = Release|Any CPU + {5BBF4A3F-4AD1-47FD-B250-05EA793F939D}.Release|x86.ActiveCfg = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE