Skip to content
This repository has been archived by the owner on May 1, 2024. It is now read-only.

Commit

Permalink
[UWP] Fixed sync of ListView items with ListViewProxy (#2512) Fixes #…
Browse files Browse the repository at this point in the history
  • Loading branch information
Pavel Yakovlev authored and rmarinho committed May 24, 2018
1 parent 3fd45e9 commit 8f3d7af
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,33 @@ protected override void Init()
}
})
};
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);
}
})
};
Expand All @@ -76,7 +95,7 @@ protected override void Init()

Content = new StackLayout
{
Children = { label, button, button1, button2, listView }
Children = { label, button, buttonI, button1, button2, listView }
};

InitializeData();
Expand Down Expand Up @@ -112,9 +131,9 @@ public void AddRange(params T[] items)
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)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ public Issue1875()

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();
Expand Down
57 changes: 51 additions & 6 deletions Xamarin.Forms.Platform.UAP/ListViewRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,15 @@
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;
Expand Down Expand Up @@ -65,8 +68,7 @@ protected override void OnElementChanged(ElementChangedEventArgs<ListView> e)
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));
Expand All @@ -79,12 +81,55 @@ protected override void OnElementChanged(ElementChangedEventArgs<ListView> e)
}
}

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());
Expand Down

0 comments on commit 8f3d7af

Please sign in to comment.