[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:
Родитель
092947adb5
Коммит
19f6d75004
|
@ -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)
|
||||
|
|
Загрузка…
Ссылка в новой задаче