This repository has been archived by the owner on May 1, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[iOS] Allow observable source update while CollectionView is not visi…
…ble (#13678) fixes #13126 * Allow item source updates while CollectionView is hidden; prevent CollectionView updates while CollectionView is hidden; fixes #13126 * Fix bug where measurement cell content is applied to the wrong cell Only force layout on transition from invisible to visible Move cell size cache to layout and clear cache on size change (e.g., rotation) Use ItemsView size for constraints when possible; * Add test for Reset situation; fix bug with Reset before CollectionView is visible;
- Loading branch information
Showing
9 changed files
with
377 additions
and
60 deletions.
There are no files selected for viewing
181 changes: 181 additions & 0 deletions
181
Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue13126.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,181 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Collections.ObjectModel; | ||
using System.Collections.Specialized; | ||
using System.ComponentModel; | ||
using System.Globalization; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
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 | ||
{ | ||
[Issue(IssueTracker.Github, 13126, "[Bug] Regression: 5.0.0-pre5 often fails to draw dynamically loaded collection view content", PlatformAffected.iOS)] | ||
#if UITEST | ||
[NUnit.Framework.Category(UITestCategories.CollectionView)] | ||
#endif | ||
public class Issue13126 : TestContentPage | ||
{ | ||
_13126VM _vm; | ||
const string Success = "Success"; | ||
|
||
protected override void Init() | ||
{ | ||
var collectionView = BindingWithConverter(); | ||
|
||
var grid = new Grid | ||
{ | ||
RowDefinitions = new RowDefinitionCollection | ||
{ | ||
new RowDefinition() { Height = GridLength.Star }, | ||
} | ||
}; | ||
|
||
grid.Children.Add(collectionView); | ||
|
||
Content = grid; | ||
|
||
_vm = new _13126VM(); | ||
BindingContext = _vm; | ||
} | ||
|
||
protected async override void OnParentSet() | ||
{ | ||
base.OnParentSet(); | ||
_vm.IsBusy = true; | ||
|
||
await Task.Delay(1000); | ||
|
||
_vm.Data.Add(Success); | ||
|
||
_vm.IsBusy = false; | ||
} | ||
|
||
internal static CollectionView BindingWithConverter() | ||
{ | ||
var cv = new CollectionView | ||
{ | ||
IsVisible = true, | ||
|
||
ItemTemplate = new DataTemplate(() => | ||
{ | ||
var label = new Label(); | ||
label.SetBinding(Label.TextProperty, new Binding(".")); | ||
return label; | ||
}) | ||
}; | ||
|
||
cv.EmptyView = new Label { Text = "Should not see me" }; | ||
|
||
cv.SetBinding(CollectionView.ItemsSourceProperty, new Binding("Data")); | ||
cv.SetBinding(VisualElement.IsVisibleProperty, new Binding("IsBusy", converter: new BoolInverter())); | ||
|
||
return cv; | ||
} | ||
|
||
class BoolInverter : IValueConverter | ||
{ | ||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) | ||
{ | ||
return !((bool)value); | ||
} | ||
|
||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) | ||
{ | ||
throw new NotImplementedException(); | ||
} | ||
} | ||
|
||
internal class _13126VM : INotifyPropertyChanged | ||
{ | ||
private bool _isBusy; | ||
|
||
public bool IsBusy | ||
{ | ||
get | ||
{ | ||
return _isBusy; | ||
} | ||
|
||
set | ||
{ | ||
_isBusy = value; | ||
OnPropertyChanged(nameof(IsBusy)); | ||
} | ||
} | ||
|
||
public OptimizedObservableCollection<string> Data { get; } = new OptimizedObservableCollection<string>(); | ||
|
||
public event PropertyChangedEventHandler PropertyChanged; | ||
|
||
void OnPropertyChanged(string name) | ||
{ | ||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); | ||
} | ||
} | ||
|
||
internal class OptimizedObservableCollection<T> : ObservableCollection<T> | ||
{ | ||
bool _shouldRaiseNotifications = true; | ||
|
||
public OptimizedObservableCollection() | ||
{ | ||
} | ||
|
||
public OptimizedObservableCollection(IEnumerable<T> collection) | ||
: base(collection) | ||
{ | ||
} | ||
|
||
public IDisposable BeginMassUpdate() | ||
{ | ||
return new MassUpdater(this); | ||
} | ||
|
||
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e) | ||
{ | ||
if (_shouldRaiseNotifications) | ||
base.OnCollectionChanged(e); | ||
} | ||
|
||
protected override void OnPropertyChanged(PropertyChangedEventArgs e) | ||
{ | ||
if (_shouldRaiseNotifications) | ||
base.OnPropertyChanged(e); | ||
} | ||
|
||
class MassUpdater : IDisposable | ||
{ | ||
readonly OptimizedObservableCollection<T> parent; | ||
public MassUpdater(OptimizedObservableCollection<T> parent) | ||
{ | ||
this.parent = parent; | ||
parent._shouldRaiseNotifications = false; | ||
} | ||
|
||
public void Dispose() | ||
{ | ||
parent._shouldRaiseNotifications = true; | ||
parent.OnPropertyChanged(new PropertyChangedEventArgs("Count")); | ||
parent.OnPropertyChanged(new PropertyChangedEventArgs("Item[]")); | ||
parent.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); | ||
} | ||
} | ||
} | ||
|
||
#if UITEST | ||
[Test] | ||
public void CollectionViewShouldSourceShouldUpdateWhileInvisible() | ||
{ | ||
RunningApp.WaitForElement(Success); | ||
} | ||
#endif | ||
} | ||
} |
74 changes: 74 additions & 0 deletions
74
Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue13126_2.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Collections.ObjectModel; | ||
using System.Collections.Specialized; | ||
using System.ComponentModel; | ||
using System.Globalization; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
using Xamarin.Forms.CustomAttributes; | ||
using Xamarin.Forms.Internals; | ||
using static Xamarin.Forms.Controls.Issues.Issue13126; | ||
|
||
#if UITEST | ||
using Xamarin.UITest; | ||
using NUnit.Framework; | ||
using Xamarin.Forms.Core.UITests; | ||
#endif | ||
|
||
namespace Xamarin.Forms.Controls.Issues | ||
{ | ||
[Issue(IssueTracker.Github, 13126, "[Bug] Regression: 5.0.0-pre5 often fails to draw dynamically loaded collection view content", | ||
PlatformAffected.iOS, issueTestNumber:1)] | ||
#if UITEST | ||
[NUnit.Framework.Category(UITestCategories.CollectionView)] | ||
#endif | ||
public class Issue13126_2 : TestContentPage | ||
{ | ||
_13126VM _vm; | ||
const string Success = "Success"; | ||
|
||
protected override void Init() | ||
{ | ||
var collectionView = BindingWithConverter(); | ||
|
||
var grid = new Grid | ||
{ | ||
RowDefinitions = new RowDefinitionCollection | ||
{ | ||
new RowDefinition() { Height = GridLength.Star }, | ||
} | ||
}; | ||
|
||
grid.Children.Add(collectionView); | ||
|
||
Content = grid; | ||
|
||
_vm = new _13126VM(); | ||
BindingContext = _vm; | ||
} | ||
|
||
protected async override void OnParentSet() | ||
{ | ||
base.OnParentSet(); | ||
_vm.IsBusy = true; | ||
|
||
await Task.Delay(1000); | ||
|
||
using (_vm.Data.BeginMassUpdate()) | ||
{ | ||
_vm.Data.Add(Success); | ||
} | ||
|
||
_vm.IsBusy = false; | ||
} | ||
|
||
#if UITEST | ||
[Test] | ||
public void CollectionViewShouldSourceShouldResetWhileInvisible() | ||
{ | ||
RunningApp.WaitForElement(Success); | ||
} | ||
#endif | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.