[UWP] Fixed code to only call ReloadData once, set CVS to null, and add correct items to internal source (#3023) fixes #3008 fixes #3009 fixes #3018 fixes #3019 fixes #2996

*  fixes #3008 and #3009

* fixed code to only call reload data once
* if itemsource is set to null then just null out CVS otherwise it'll cause a COM Exception
* added ListView Categories to some tests to more easily run targeted tests against UWP
* fixed a couple UWP tests that weren't passing

* * fixes #3018
* fixes #3019
* fixes #2996
* The wrong object was being added to the internal collection

* * add test case for listview initailized as null
This commit is contained in:
Shane Neuville 2018-06-15 05:34:47 -06:00 коммит произвёл Rui Marinho
Родитель 092947adb5
Коммит 19f6d75004
12 изменённых файлов: 518 добавлений и 66 удалений

Просмотреть файл

@ -12,6 +12,7 @@ using Xamarin.Forms.Internals;
#if UITEST
using NUnit.Framework;
using Xamarin.UITest;
using Xamarin.Forms.Core.UITests;
#endif
namespace Xamarin.Forms.Controls
@ -318,6 +319,9 @@ namespace Xamarin.Forms.Controls.Issues
{
[Preserve(AllMembers = true)]
[Issue(IssueTracker.None, 0, "Adding Multiple Items to a ListView", PlatformAffected.All)]
#if UITEST
[NUnit.Framework.Category(UITestCategories.ListView)]
#endif
public class AddingMultipleItemsListView : TestContentPage
{
protected override void Init()

Просмотреть файл

@ -10,12 +10,16 @@ using System;
#if UITEST
using Xamarin.UITest;
using NUnit.Framework;
using Xamarin.Forms.Core.UITests;
#endif
namespace Xamarin.Forms.Controls.Issues
{
[Preserve(AllMembers = true)]
[Issue(IssueTracker.Bugzilla, 56771, "Multi-item add in INotifyCollectionChanged causes a NSInternalInconsistencyException in bindings on iOS", PlatformAffected.iOS)]
#if UITEST
[NUnit.Framework.Category(UITestCategories.ListView)]
#endif
public class Bugzilla56771 : TestContentPage
{
const string Success = "Success";

Просмотреть файл

@ -8,12 +8,16 @@ using Xamarin.Forms.Internals;
#if UITEST
using Xamarin.UITest;
using NUnit.Framework;
using Xamarin.Forms.Core.UITests;
#endif
namespace Xamarin.Forms.Controls.Issues
{
[Preserve(AllMembers = true)]
[Issue(IssueTracker.None, 5955, "Group ListView Crashes when ItemSource is Cleared", PlatformAffected.iOS)]
#if UITEST
[Category(UITestCategories.ListView)]
#endif
public class GroupListViewHeaderIndexOutOfRange : TestContentPage
{
const string ButtonId = "button";

Просмотреть файл

@ -0,0 +1,19 @@
#if UITEST
using System;
using System.Collections.Generic;
using System.Text;
using Xamarin.UITest;
using NUnit.Framework;
using Xamarin.UITest.Queries;
namespace Xamarin.Forms.Controls.Issues
{
public static class UITestHelper
{
public static string ReadText(this AppResult result) =>
result.Text ?? result.Description;
}
}
#endif

Просмотреть файл

@ -135,23 +135,23 @@ namespace Xamarin.Forms.Controls.Issues
RunningApp.WaitForElement(q => q.Marked(A));
RunningApp.Tap(q => q.Marked(A));
Assert.AreEqual(A, RunningApp.WaitForElement(q => q.Marked(lblItem))[0].Text);
Assert.AreEqual(Group_1, RunningApp.WaitForElement(q => q.Marked(lblGroup))[0].Text);
Assert.AreEqual(A, RunningApp.WaitForElement(q => q.Marked(lblItem))[0].ReadText());
Assert.AreEqual(Group_1, RunningApp.WaitForElement(q => q.Marked(lblGroup))[0].ReadText());
RunningApp.Tap(q => q.Marked(B));
Assert.AreEqual(B, RunningApp.WaitForElement(q => q.Marked(lblItem))[0].Text);
Assert.AreEqual(Group_1, RunningApp.WaitForElement(q => q.Marked(lblGroup))[0].Text);
Assert.AreEqual(B, RunningApp.WaitForElement(q => q.Marked(lblItem))[0].ReadText());
Assert.AreEqual(Group_1, RunningApp.WaitForElement(q => q.Marked(lblGroup))[0].ReadText());
RunningApp.Tap(q => q.Marked(C));
Assert.AreEqual(C, RunningApp.WaitForElement(q => q.Marked(lblItem))[0].Text);
Assert.AreEqual(Group_2, RunningApp.WaitForElement(q => q.Marked(lblGroup))[0].Text);
Assert.AreEqual(C, RunningApp.WaitForElement(q => q.Marked(lblItem))[0].ReadText());
Assert.AreEqual(Group_2, RunningApp.WaitForElement(q => q.Marked(lblGroup))[0].ReadText());
RunningApp.Tap(q => q.Marked(D));
Assert.AreEqual(D, RunningApp.WaitForElement(q => q.Marked(lblItem))[0].Text);
Assert.AreEqual(Group_2, RunningApp.WaitForElement(q => q.Marked(lblGroup))[0].Text);
Assert.AreEqual(D, RunningApp.WaitForElement(q => q.Marked(lblItem))[0].ReadText());
Assert.AreEqual(Group_2, RunningApp.WaitForElement(q => q.Marked(lblGroup))[0].ReadText());
}
#endif
}

Просмотреть файл

@ -8,32 +8,49 @@ using System.Threading.Tasks;
using Xamarin.Forms.CustomAttributes;
using Xamarin.Forms.Internals;
namespace Xamarin.Forms.Controls
#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, 1875, "NSRangeException adding items through ItemAppearing", PlatformAffected.iOS)]
[Preserve(AllMembers = true)]
[Issue(IssueTracker.Github, 1875, "NSRangeException adding items through ItemAppearing", PlatformAffected.iOS)]
#if UITEST
[NUnit.Framework.Category(UITestCategories.ListView)]
#endif
public class Issue1875
: ContentPage
: TestContentPage
{
public Issue1875()
MainViewModel _viewModel;
int _start = 0;
const int NumberOfRecords = 15;
protected override void Init()
{
Button loadData = new Button { Text = "Load", HorizontalOptions = LayoutOptions.FillAndExpand };
ListView mainList = new ListView {
ListView mainList = new ListView
{
VerticalOptions = LayoutOptions.FillAndExpand,
HorizontalOptions = LayoutOptions.FillAndExpand
};
mainList.SetBinding (ListView.ItemsSourceProperty, "Items");
mainList.SetBinding(ListView.ItemsSourceProperty, "Items");
_viewModel = new MainViewModel ();
_viewModel = new MainViewModel();
BindingContext = _viewModel;
loadData.Clicked += async (sender, e) => {
await LoadData ();
loadData.Clicked += async (sender, e) =>
{
await LoadData();
};
mainList.ItemAppearing += OnItemAppearing;
Content = new StackLayout {
Content = new StackLayout
{
Children = {
loadData,
mainList
@ -41,10 +58,6 @@ namespace Xamarin.Forms.Controls
};
}
readonly MainViewModel _viewModel;
int _start = 0;
const int NumberOfRecords = 15;
async void OnItemAppearing(object sender, ItemVisibilityEventArgs e)
{
if (e.Item == null)
@ -54,9 +67,9 @@ namespace Xamarin.Forms.Controls
await LoadData();
}
async Task LoadData ()
async Task LoadData()
{
await _viewModel.LoadData (_start, NumberOfRecords);
await _viewModel.LoadData(_start, NumberOfRecords);
_start = _start + NumberOfRecords;
}
@ -64,47 +77,64 @@ namespace Xamarin.Forms.Controls
{
public event PropertyChangedEventHandler PropertyChanged;
public MainViewModel ()
public MainViewModel()
{
}
ObservableCollection<int> _items;
public ObservableCollection<int> Items {
get {
public ObservableCollection<int> Items
{
get
{
if (_items == null)
_items = new ObservableCollection<int> ();
_items = new ObservableCollection<int>();
return _items;
}
set {
set
{
_items = value;
PropertyChanged (this, new PropertyChangedEventArgs ("Items"));
PropertyChanged(this, new PropertyChangedEventArgs("Items"));
}
}
bool _isLoading;
public bool IsLoading {
get {
public bool IsLoading
{
get
{
return _isLoading;
}
set {
if (_isLoading != value) {
set
{
if (_isLoading != value)
{
_isLoading = value;
PropertyChanged (this, new PropertyChangedEventArgs ("IsLoading"));
PropertyChanged(this, new PropertyChangedEventArgs("IsLoading"));
}
}
}
#pragma warning disable 1998 // considered for removal
public async Task LoadData (int start, int numberOfRecords)
public async Task LoadData(int start, int numberOfRecords)
#pragma warning restore 1998
{
IsLoading = true;
for (int counter = 0; counter < numberOfRecords; counter++)
Items.Add (start + counter);
Items.Add(start + counter);
IsLoading = false;
}
}
#if UITEST
[Test]
public void NSRangeException()
{
RunningApp.WaitForElement(q => q.Marked("Load"));
RunningApp.Tap(q => q.Marked("Load"));
RunningApp.WaitForElement(q => q.Marked("5"));
}
#endif
}
}

Просмотреть файл

@ -9,6 +9,7 @@ using Xamarin.Forms.Internals;
#if UITEST
using Xamarin.UITest;
using NUnit.Framework;
using Xamarin.Forms.Core.UITests;
#endif
namespace Xamarin.Forms.Controls.Issues
@ -16,6 +17,9 @@ namespace Xamarin.Forms.Controls.Issues
[Preserve(AllMembers = true)]
[Issue(IssueTracker.Github, 1975, "[iOS] ListView throws NRE when grouping enabled and data changed",
PlatformAffected.iOS)]
#if UITEST
[NUnit.Framework.Category(UITestCategories.ListView)]
#endif
public class Issue1975 : TestNavigationPage
{
protected override void Init()
@ -37,7 +41,7 @@ namespace Xamarin.Forms.Controls.Issues
lv.SetBinding(ListView.ItemsSourceProperty, new Binding("Items"));
lv.IsGroupingEnabled = true;
lv.GroupDisplayBinding = new Binding("Description");
lv.GroupShortNameBinding= new Binding("ShortName");
lv.GroupShortNameBinding = new Binding("ShortName");
lv.ItemTemplate = new DataTemplate(() =>
{
@ -49,16 +53,16 @@ namespace Xamarin.Forms.Controls.Issues
var layout = new StackLayout();
layout.Children.Add(button);
layout.Children.Add(lv);
return new ContentPage { Content = layout, BindingContext = DataSample.Instance };
}
ContentPage ModifyDataPage()
{
var contentPage = new ContentPage { Content = new Label { Text = Success, Margin = 100} };
var contentPage = new ContentPage { Content = new Label { Text = Success, Margin = 100 } };
contentPage.Appearing += (sender, args) =>
DataSample.Instance.Items.Add(new Item("C"){new SubItem("Cherry"), new SubItem("Cranberry")});
contentPage.Appearing += (sender, args) =>
DataSample.Instance.Items.Add(new Item("C") { new SubItem("Cherry"), new SubItem("Cranberry") });
return contentPage;
}
@ -137,7 +141,7 @@ namespace Xamarin.Forms.Controls.Issues
#if UITEST
[Test]
public void UpdatingSourceOfDisposedListViewDoesNotCrash ()
public void UpdatingSourceOfDisposedListViewDoesNotCrash()
{
RunningApp.Tap(Go);
RunningApp.WaitForElement(Success);

Просмотреть файл

@ -15,7 +15,7 @@ namespace Xamarin.Forms.Controls.Issues
#endif
[Preserve(AllMembers = true)]
[Issue(IssueTracker.Github, 2929, "[UWP] ListView with null ItemsSource crashes on 3.0.0.530893",
[Issue(IssueTracker.Github, 2929, "[UWP] ListView with null ItemsSource crashes on 3.0.0.530893",
PlatformAffected.UWP)]
public class Issue2929 : TestContentPage
{
@ -53,7 +53,7 @@ namespace Xamarin.Forms.Controls.Issues
#endif
[Preserve(AllMembers = true)]
[Issue(IssueTracker.None, 99, "Make sure setting ItemSource to null doesn't blow up",
[Issue(IssueTracker.None, 99, "Make sure setting ItemSource to null doesn't blow up",
PlatformAffected.UWP)]
public class SetListViewItemSourceToNull : TestContentPage
{
@ -100,6 +100,7 @@ namespace Xamarin.Forms.Controls.Issues
#if UITEST
[Test]
[NUnit.Framework.Category(UITestCategories.ListView)]
public void SettingItemsSourceToNullDoesNotCrash()
{
RunningApp.WaitForElement(Go);

Просмотреть файл

@ -0,0 +1,216 @@
using System;
using Xamarin.Forms.CustomAttributes;
using System.Diagnostics;
using Xamarin.Forms.Internals;
using System.Collections.Generic;
using System.Linq;
using System.Collections.ObjectModel;
#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, 3008, "Setting ListView.ItemSource to null doesn't cause it clear out its contents", PlatformAffected.UWP)]
#if UITEST
[NUnit.Framework.Category(UITestCategories.ListView)]
#endif
public class Issue3008 : TestContentPage
{
ListView _listView;
ListView _listViewIsGrouped;
const string success1 = "InitialLoad: you should see a grouped and not grouped list view";
const string successEmpty1 = "Source is set to null: you should see nothing";
const string success2 = "Reload1: you should see a grouped and not grouped list view";
const string successEmpty2 = "If you see nothing now test has passed";
const string successEmpty3 = "List loaded and ItemSource not set: you should see nothing";
[Preserve(AllMembers = true)]
class MyHeaderViewCell : ViewCell
{
public MyHeaderViewCell()
{
Height = 25;
var label = new Label { VerticalOptions = LayoutOptions.Center };
label.SetBinding(Label.TextProperty, nameof(GroupedItem.Name));
View = label;
}
}
[Preserve(AllMembers = true)]
class GroupedItem : List<Item>
{
public GroupedItem()
{
AddRange(Enumerable.Range(0, 3).Select(i => new Item()));
}
public string Name { get; set; }
}
[Preserve(AllMembers = true)]
class Item
{
}
void LoadData()
{
_listViewIsGrouped.ItemsSource = new ObservableCollection<GroupedItem>(Enumerable.Range(0, 3).Select(x => new GroupedItem() { Name = $"Group {x}" }));
_listView.ItemsSource = new ObservableCollection<Item>(Enumerable.Range(0, 13).Select(x => new Item()));
}
void ReloadListViews()
{
StackLayout content = Content as StackLayout;
if (_listView != null)
{
content.Children.Remove(_listView);
content.Children.Remove(_listViewIsGrouped);
}
_listView = new ListView
{
ItemTemplate = new DataTemplate(() =>
{
Label nameLabel = new Label() { Text = "Not Grouped Item" };
var cell = new ViewCell
{
View = nameLabel,
};
return cell;
}),
};
_listViewIsGrouped = new ListView
{
IsGroupingEnabled = true,
GroupHeaderTemplate = new DataTemplate(typeof(MyHeaderViewCell)),
ItemTemplate = new DataTemplate(() =>
{
Label nameLabel = new Label() { Text = "Grouped Item" };
var cell = new ViewCell
{
View = nameLabel,
};
return cell;
}),
};
content.Children.Add(_listView);
content.Children.Add(_listViewIsGrouped);
}
protected override void Init()
{
Label label = new Label();
int clickCount = 0;
Content = new StackLayout
{
Children =
{
label,
new Button()
{
Text = "Click Until Success",
Command = new Command(() =>
{
if(clickCount == 0)
{
LoadData();
label.Text = success1;
}
else if(clickCount == 1)
{
ReloadListViews();
LoadData();
label.Text = success1;
}
else if(clickCount <= 3)
{
if(_listViewIsGrouped.ItemsSource != null)
{
_listViewIsGrouped.ItemsSource = null;
_listView.ItemsSource = null;
label.Text = successEmpty1;
}
else
{
LoadData();
label.Text = success2;
}
}
else if(clickCount <= 5)
{
if(_listViewIsGrouped.ItemsSource != null)
{
ReloadListViews();
label.Text = successEmpty3;
}
else
{
LoadData();
label.Text = success2;
}
}
else
{
if(_listViewIsGrouped.ItemsSource != null)
{
_listViewIsGrouped.ItemsSource = new List<GroupedItem>();
_listView.ItemsSource = new List<Item>();
label.Text = successEmpty2;
}
}
clickCount++;
})
}
},
};
ReloadListViews();
}
#if UITEST && !__ANDROID__
[Test]
public void EnsureListViewEmptiesOut()
{
RunningApp.Tap("Click Until Success");
RunningApp.WaitForElement("Not Grouped Item");
RunningApp.WaitForElement("Grouped Item");
RunningApp.Tap("Click Until Success");
RunningApp.WaitForElement("Not Grouped Item");
RunningApp.WaitForElement("Grouped Item");
RunningApp.Tap("Click Until Success");
RunningApp.WaitForNoElement("Not Grouped Item");
RunningApp.WaitForNoElement("Grouped Item");
RunningApp.Tap("Click Until Success");
RunningApp.WaitForElement("Not Grouped Item");
RunningApp.WaitForElement("Grouped Item");
RunningApp.Tap("Click Until Success");
RunningApp.WaitForNoElement("Not Grouped Item");
RunningApp.WaitForNoElement("Grouped Item");
RunningApp.Tap("Click Until Success");
RunningApp.WaitForElement("Not Grouped Item");
RunningApp.WaitForElement("Grouped Item");
RunningApp.Tap("Click Until Success");
RunningApp.WaitForNoElement("Not Grouped Item");
RunningApp.WaitForNoElement("Grouped Item");
}
#endif
}
}

Просмотреть файл

@ -0,0 +1,160 @@
using System;
using Xamarin.Forms.CustomAttributes;
using System.Diagnostics;
using Xamarin.Forms.Internals;
using System.Collections.Generic;
using System.Linq;
using System.Collections.ObjectModel;
#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, 3019, "Grouped ListView Header empty for adding items", PlatformAffected.UWP)]
#if UITEST
[Category(UITestCategories.ListView)]
#endif
public class Issue3019 : TestContentPage
{
ListView _listViewIsGrouped;
[Preserve(AllMembers = true)]
class MyHeaderViewCell : ViewCell
{
public MyHeaderViewCell()
{
Height = 25;
var label = new Label { VerticalOptions = LayoutOptions.Center };
label.SetBinding(Label.TextProperty, nameof(GroupedItem.Name));
View = new StackLayout()
{
Children =
{
label
}
};
}
}
[Preserve(AllMembers = true)]
class Item
{
static int counter = 0;
public Item()
{
Text = $"Grouped Item: {counter++}";
}
public string Text { get; }
}
[Preserve(AllMembers = true)]
class GroupedItem : List<Item>
{
public GroupedItem()
{
AddRange(Enumerable.Range(0, 1).Select(i => new Item()));
}
public string Name { get; set; }
}
void LoadData()
{
_listViewIsGrouped.ItemsSource = new ObservableCollection<GroupedItem>(Enumerable.Range(0, 1).Select(x => new GroupedItem() { Name = $"Group {x}" }));
}
void AddData()
{
var list = _listViewIsGrouped.ItemsSource as IList<GroupedItem>;
list.Add(new GroupedItem() { Name = $"Group {list.Count}" });
}
void ReloadListViews()
{
StackLayout content = Content as StackLayout;
if (_listViewIsGrouped != null)
{
content.Children.Remove(_listViewIsGrouped);
}
_listViewIsGrouped = new ListView
{
IsGroupingEnabled = true,
GroupHeaderTemplate = new DataTemplate(typeof(MyHeaderViewCell)),
ItemTemplate = new DataTemplate(() =>
{
Label nameLabel = new Label();
nameLabel.SetBinding(Label.TextProperty, "Text");
var cell = new ViewCell
{
View = nameLabel,
};
return cell;
}),
ItemsSource = new ObservableCollection<GroupedItem>()
};
content.Children.Add(_listViewIsGrouped);
}
protected override void OnAppearing()
{
base.OnAppearing();
AddData();
}
protected override void Init()
{
Label label = new Label() { Text = "If you see two group headers and can click on each row without crashing test has passed" };
Content = new StackLayout
{
Children =
{
label,
new Button()
{
Text = "Click to add more rows",
Command = new Command(() =>
{
AddData();
})
}
},
};
ReloadListViews();
LoadData();
_listViewIsGrouped.ItemSelected += (sender, args) =>
{
label.Text = (args.SelectedItem as Item).Text + " Clicked";
};
}
#if UITEST
[Test]
public void MakeSureListGroupShowsUpAndItemsAreClickable()
{
RunningApp.WaitForElement("Group 1");
RunningApp.Tap(x => x.Marked("Grouped Item: 0"));
RunningApp.Tap(x => x.Marked("Grouped Item: 1"));
RunningApp.Tap(x => x.Marked("Grouped Item: 1 Clicked"));
}
#endif
}
}

Просмотреть файл

@ -239,6 +239,7 @@
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla59580.cs" />
<Compile Include="$(MSBuildThisFileDirectory)GitHub1878.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Helpers\ISampleNativeControl.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Helpers\UITestHelper.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Helpers\ViewHelper.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue1396.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue1415.cs" />
@ -319,6 +320,8 @@
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla32462.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla36681.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla36479.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue3008.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue3019.cs" />
<Compile Include="$(MSBuildThisFileDirectory)MapsModalCrash.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ModalActivityIndicatorTest.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla37625.cs" />

Просмотреть файл

@ -83,14 +83,16 @@ namespace Xamarin.Forms.Platform.UWP
void ReloadData()
{
if (Element?.ItemsSource == null)
{
return;
}
if (Element?.ItemsSource == null && _context != null)
_context.Source = null;
var allSourceItems = new ObservableCollection<object>();
foreach (var item in Element.ItemsSource)
allSourceItems.Add(item);
if (Element?.ItemsSource != null)
{
foreach (var item in Element.ItemsSource)
allSourceItems.Add(item);
}
// WinRT throws an exception if you set ItemsSource directly to a CVS, so bind it.
List.DataContext = _context = new CollectionViewSource
@ -108,11 +110,24 @@ namespace Xamarin.Forms.Platform.UWP
if (e.NewStartingIndex < 0)
goto case NotifyCollectionChangedAction.Reset;
for (int i = e.NewItems.Count - 1; i >= 0; i--)
SourceItems.Insert(e.NewStartingIndex, e.NewItems[i]);
// if a NewStartingIndex that's too high is passed in just add the items.
// I realize this is enforcing bad behavior but prior to this synchronization
// code being added it wouldn't cause the app to crash whereas now it does
// so this code accounts for that in order to ensure smooth sailing for the user
if (e.NewStartingIndex >= SourceItems.Count)
{
for (int i = 0; i < e.NewItems.Count; i++)
SourceItems.Add((e.NewItems[i] as BindableObject).BindingContext);
}
else
{
for (int i = e.NewItems.Count - 1; i >= 0; i--)
SourceItems.Insert(e.NewStartingIndex, (e.NewItems[i] as BindableObject).BindingContext);
}
break;
case NotifyCollectionChangedAction.Remove:
foreach (var item in e.OldItems)
for (int i = e.OldItems.Count - 1; i >= 0; i--)
SourceItems.RemoveAt(e.OldStartingIndex);
break;
case NotifyCollectionChangedAction.Move:
@ -133,6 +148,7 @@ namespace Xamarin.Forms.Platform.UWP
case NotifyCollectionChangedAction.Replace:
case NotifyCollectionChangedAction.Reset:
default:
ClearSizeEstimate();
ReloadData();
break;
}
@ -168,11 +184,6 @@ namespace Xamarin.Forms.Platform.UWP
{
ClearSizeEstimate();
}
else if (e.PropertyName == ListView.ItemsSourceProperty.PropertyName)
{
ClearSizeEstimate();
ReloadData();
}
else if (e.PropertyName == Specifics.SelectionModeProperty.PropertyName)
{
UpdateSelectionMode();
@ -274,14 +285,10 @@ namespace Xamarin.Forms.Platform.UWP
void UpdateGrouping()
{
if (Element?.ItemsSource == null)
{
return;
}
bool grouping = Element.IsGroupingEnabled;
((CollectionViewSource)List.DataContext).IsSourceGrouped = grouping;
if (_context != null)
_context.IsSourceGrouped = grouping;
var templatedItems = TemplatedItemsView.TemplatedItems;
if (grouping && templatedItems.ShortNames != null)