[UWP] Fixed sync of ListView items with ListViewProxy (#2512) Fixes #2485

This commit is contained in:
Pavel Yakovlev 2018-05-24 16:44:36 +03:00 коммит произвёл Rui Marinho
Родитель 3fd45e9697
Коммит 8f3d7af41b
3 изменённых файлов: 77 добавлений и 11 удалений

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

@ -52,14 +52,33 @@ namespace Xamarin.Forms.Controls.Issues
}
})
};
var buttonI = new Button
{
Text = "Insert odd",
AutomationId = BtnAdd,
Command = new Command(() =>
{
try
{
for (int j = 1; j < data.Count; j += 2)
{
data.Insert(j, $"Item {++i} inserted");
}
}
catch (ArgumentException)
{
label.Text = Success;
}
})
};
var button1 = new Button
{
Text = "Remove 2",
Command = new Command(() =>
{
if (data.Count > 1)
if (data.Count > 3)
{
data.RemoveRangeAt(0, 2);
data.RemoveRangeAt(2, 2);
}
})
};
@ -76,7 +95,7 @@ namespace Xamarin.Forms.Controls.Issues
Content = new StackLayout
{
Children = { label, button, button1, button2, listView }
Children = { label, button, buttonI, button1, button2, listView }
};
InitializeData();
@ -112,9 +131,9 @@ namespace Xamarin.Forms.Controls.Issues
public void InsertRangeAt(int startIndex, params T[] items)
{
int idx = this.Count;
foreach (var item in items)
for (int i = items.Length - 1; i >= 0; i--)
{
base.Items.Insert(startIndex++, item);
base.Items.Insert(startIndex, items[i]);
}
if (idx < Count)
{

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

@ -47,6 +47,8 @@ namespace Xamarin.Forms.Controls
async void OnItemAppearing(object sender, ItemVisibilityEventArgs e)
{
if (e.Item == null)
return;
var item = (int)e.Item;
if (!_viewModel.IsLoading && item == _viewModel.Items.Last())
await LoadData();

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

@ -18,12 +18,15 @@ using WApp = Windows.UI.Xaml.Application;
using Xamarin.Forms.Internals;
using Xamarin.Forms.PlatformConfiguration.WindowsSpecific;
using Specifics = Xamarin.Forms.PlatformConfiguration.WindowsSpecific.ListView;
using System.Collections.ObjectModel;
namespace Xamarin.Forms.Platform.UWP
{
public class ListViewRenderer : ViewRenderer<ListView, FrameworkElement>
{
ITemplatedItemsView<Cell> TemplatedItemsView => Element;
ObservableCollection<object> SourceItems => context?.Source as ObservableCollection<object>;
CollectionViewSource context;
bool _itemWasClicked;
bool _subscribedToItemClick;
bool _subscribedToTapped;
@ -65,8 +68,7 @@ namespace Xamarin.Forms.Platform.UWP
List.SetBinding(ItemsControl.ItemsSourceProperty, "");
}
// WinRT throws an exception if you set ItemsSource directly to a CVS, so bind it.
List.DataContext = new CollectionViewSource { Source = Element.ItemsSource, IsSourceGrouped = Element.IsGroupingEnabled };
ReloadData();
if (Element.SelectedItem != null)
OnElementItemSelected(null, new SelectedItemChangedEventArgs(Element.SelectedItem));
@ -79,12 +81,55 @@ namespace Xamarin.Forms.Platform.UWP
}
}
void OnCollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
void ReloadData()
{
if (e.Action == NotifyCollectionChangedAction.Reset)
var allSourceItems = new ObservableCollection<object>();
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
{
List.DataContext =
new CollectionViewSource { Source = Element.ItemsSource, IsSourceGrouped = Element.IsGroupingEnabled };
Source = allSourceItems,
IsSourceGrouped = Element.IsGroupingEnabled
};
}
void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
switch (e.Action)
{
case NotifyCollectionChangedAction.Add:
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]);
break;
case NotifyCollectionChangedAction.Remove:
foreach (var item in e.OldItems)
SourceItems.RemoveAt(e.OldStartingIndex);
break;
case NotifyCollectionChangedAction.Move:
for (var i = 0; i < e.OldItems.Count; i++)
{
var oldi = e.OldStartingIndex;
var newi = e.NewStartingIndex;
if (e.NewStartingIndex < e.OldStartingIndex)
{
oldi += i;
newi += i;
}
SourceItems.Move(oldi, newi);
}
break;
case NotifyCollectionChangedAction.Replace:
case NotifyCollectionChangedAction.Reset:
default:
ReloadData();
break;
}
Device.BeginInvokeOnMainThread(() => List.UpdateLayout());