Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add InvalidateItems to the Adapter #40

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion Sample/VirtualListViewSample/Section.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,20 @@
namespace VirtualListViewSample;

public class Section : List<string>
public class Section : List<Item>
{
public string Title { get; set; }
}


public class Item : BindableObject
{

public static readonly BindableProperty NameProperty =
BindableProperty.Create(nameof(Name), typeof(string), typeof(Item), string.Empty);

public string Name
{
get => (string)GetValue(NameProperty);
set => SetValue(NameProperty, value);
}
}
18 changes: 15 additions & 3 deletions Sample/VirtualListViewSample/SectionedAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace VirtualListViewSample;

public class SectionedAdapter : VirtualListViewAdapterBase<Section, string>
public class SectionedAdapter : VirtualListViewAdapterBase<Section, Item>
{
public SectionedAdapter(IList<Section> items) : base()
{
Expand All @@ -20,7 +20,7 @@ public override int GetNumberOfSections()
public override int GetNumberOfItemsInSection(int sectionIndex)
=> Items[sectionIndex].Count;

public override string GetItem(int sectionIndex, int itemIndex)
public override Item GetItem(int sectionIndex, int itemIndex)
=> Items[sectionIndex][itemIndex];

public void AddItem(string sectionTitle, string itemName)
Expand All @@ -33,7 +33,7 @@ public void AddItem(string sectionTitle, string itemName)
Items.Add(section);
}

section.Add(itemName);
section.Add(new Item { Name = itemName });
InvalidateData();
}

Expand All @@ -51,4 +51,16 @@ public void RemoveItem(int sectionIndex, int itemIndex)

InvalidateData();
}

public void UpdateItem(int sectionIndex, int itemIndex)
{
var section = Items.ElementAtOrDefault(sectionIndex);

if (section is null)
return;

section[itemIndex].Name = $"{section[itemIndex].Name} Updated";

InvalidateItems(new ItemPosition(sectionIndex, itemIndex));
}
}
21 changes: 13 additions & 8 deletions Sample/VirtualListViewSample/SectionedAdapterPage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,19 @@
</DataTemplate>
</vlv:VirtualListView.SectionHeaderTemplate>
<vlv:VirtualListView.ItemTemplate>
<DataTemplate>
<Border
Margin="10,0,0,0"
Padding="4"
Background="LightBlue"
StrokeShape="{RoundRectangle CornerRadius=10}">
<Label Margin="10,6,10,6" Text="{Binding .}" />
</Border>
<DataTemplate x:DataType="local:Item">
<vlv:VirtualViewCell x:Name="cell">
<Border
Margin="10,0,0,0"
Padding="4"
Background="LightBlue"
StrokeShape="{RoundRectangle CornerRadius=10}">
<VerticalStackLayout>
<Button Text="Test" Clicked="ButtonAddTextClicked" CommandParameter="{DynamicResource ItemPosition}" />
<Label Margin="10,6,10,6" Text="{Binding Name}" />
</VerticalStackLayout>
</Border>
</vlv:VirtualViewCell>
</DataTemplate>
</vlv:VirtualListView.ItemTemplate>
</vlv:VirtualListView>
Expand Down
12 changes: 12 additions & 0 deletions Sample/VirtualListViewSample/SectionedAdapterPage.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using CommunityToolkit.Mvvm.Input;
using System.Collections.ObjectModel;

namespace VirtualListViewSample;
Expand Down Expand Up @@ -53,4 +54,15 @@ private async void Vlv_OnOnRefresh(object sender, RefreshEventArgs e)
await Task.Delay(3000);
e.Complete();
}

private void ButtonAddTextClicked(object sender, EventArgs e)
{
if (sender is Button button)
{
if (button.CommandParameter is ItemPosition itemPosition)
{
this.Adapter.UpdateItem(itemPosition.SectionIndex, itemPosition.ItemIndex);
}
}
}
}
4 changes: 4 additions & 0 deletions VirtualListView/Adapters/IVirtualListViewAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,8 @@ public interface IVirtualListViewAdapter
event EventHandler OnDataInvalidated;

void InvalidateData();

event EventHandler<InvalidateItemsEventArgs> OnItemsInvalidated;

void InvalidateItems(params ItemPosition[] items);
}
11 changes: 11 additions & 0 deletions VirtualListView/Adapters/InvalidateItemsEventArgs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace Microsoft.Maui.Adapters;

public class InvalidateItemsEventArgs : EventArgs
{
public InvalidateItemsEventArgs(params ItemPosition[] items)
{
Items = items;
}

public ItemPosition[] Items { get; }
}
10 changes: 10 additions & 0 deletions VirtualListView/Adapters/VirtualListViewAdapterBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ public virtual int GetNumberOfSections() =>

public event EventHandler OnDataInvalidated;

public event EventHandler<InvalidateItemsEventArgs> OnItemsInvalidated;

public virtual void InvalidateData()
{
OnDataInvalidated?.Invoke(this, EventArgs.Empty);
Expand All @@ -31,4 +33,12 @@ object IVirtualListViewAdapter.GetSection(int sectionIndex)

void IVirtualListViewAdapter.InvalidateData()
=> InvalidateData();

public virtual void InvalidateItems(params ItemPosition[] items)
{
OnItemsInvalidated?.Invoke(this, new InvalidateItemsEventArgs(items));
}

void IVirtualListViewAdapter.InvalidateItems(params Microsoft.Maui.ItemPosition[] items)
=> InvalidateItems(items);
}
20 changes: 20 additions & 0 deletions VirtualListView/Apple/VirtualListViewHandler.ios.maccatalyst.cs
Original file line number Diff line number Diff line change
Expand Up @@ -255,4 +255,24 @@ public void InvalidateData()
});

}

void InvalidateItems(params ItemPosition[] items)
{
if (items is not null && items.Length > 0)
{
var paths = new List<NSIndexPath>();
foreach (var item in items)
{
paths.Add(NSIndexPath.FromItemSection(item.ItemIndex, item.SectionIndex));
}

if (paths.Count > 0)
{
this.PlatformView.InvokeOnMainThread(() =>
{
PlatformView.ReloadItems(paths.ToArray());
});
}
}
}
}
2 changes: 2 additions & 0 deletions VirtualListView/Controls/VirtualViewCell.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ public int SectionIndex
{
sectionIndex = value;
this.Resources[nameof(SectionIndex)] = sectionIndex;
this.Resources[nameof(ItemPosition)] = new ItemPosition(sectionIndex, ItemIndex);
this.OnPropertyChanged(nameof(SectionIndex));
}
}
Expand All @@ -73,6 +74,7 @@ public int ItemIndex
{
itemIndex = value;
this.Resources[nameof(ItemIndex)] = itemIndex;
this.Resources[nameof(ItemPosition)] = new ItemPosition(SectionIndex, itemIndex);
this.OnPropertyChanged(nameof(ItemIndex));
this.OnPropertyChanged(nameof(IsFirstItemInSection));
this.OnPropertyChanged(nameof(IsNotFirstItemInSection));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,19 @@ void UpdateEmptyView()
UpdateEmptyViewVisibility();
}
}

void InvalidateItems(params ItemPosition[] items)
{
if (items is not null && items.Length > 0)
{
foreach (var item in items)
{
var rawPosition = PositionalViewSelector.GetPosition(item.SectionIndex, item.ItemIndex);

adapter.NotifyItemChanged(rawPosition);
}
}
}

ScrollBarVisibility _defaultHorizontalScrollVisibility = ScrollBarVisibility.Default;
ScrollBarVisibility _defaultVerticalScrollVisibility = ScrollBarVisibility.Default;
Expand Down
7 changes: 7 additions & 0 deletions VirtualListView/Platforms/Windows/IrSource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Reflection;

namespace Microsoft.Maui;

Expand All @@ -26,6 +27,12 @@ public void Reset()
CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}

public void ResetItems(params ItemPosition[] items)
{
// TODO: Fire a more specific event
Reset();
}

public int Count
=> PositionalViewSelector?.TotalCount ?? 0;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,12 @@ void UpdateEmptyView()
UpdateEmptyViewVisibility();
}

void InvalidateItems(params ItemPosition[] items)
{
if (items is not null && items.Length > 0)
irSource?.ResetItems(items);
}

void UpdateVerticalScrollbarVisibility(ScrollBarVisibility scrollBarVisibility)
{
scrollViewer.VerticalScrollBarVisibility = scrollBarVisibility switch
Expand Down
13 changes: 12 additions & 1 deletion VirtualListView/VirtualListViewHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public partial class VirtualListViewHandler

public static CommandMapper<IVirtualListView, VirtualListViewHandler> CommandMapper = new(ViewCommandMapper)
{
[nameof(IVirtualListView.ScrollToItem)] = MapScrollToItem,
[nameof(IVirtualListView.ScrollToItem)] = MapScrollToItem
};

public static void MapScrollToItem(VirtualListViewHandler handler, IVirtualListView view, object parameter)
Expand Down Expand Up @@ -69,10 +69,16 @@ bool ShouldShowEmptyView
public static void MapAdapter(VirtualListViewHandler handler, IVirtualListView virtualListView)
{
if (handler.currentAdapter != null)
{
handler.currentAdapter.OnDataInvalidated -= handler.Adapter_OnDataInvalidated;
handler.currentAdapter.OnItemsInvalidated -= handler.Adapter_OnItemsInvalidated;
}

if (virtualListView?.Adapter != null)
{
virtualListView.Adapter.OnDataInvalidated += handler.Adapter_OnDataInvalidated;
virtualListView.Adapter.OnItemsInvalidated += handler.Adapter_OnItemsInvalidated;
}

handler.currentAdapter = virtualListView.Adapter;
handler?.InvalidateData();
Expand All @@ -85,6 +91,11 @@ void Adapter_OnDataInvalidated(object sender, EventArgs e)
InvalidateData();
}

void Adapter_OnItemsInvalidated(object sender, InvalidateItemsEventArgs e)
{
InvalidateItems(e.Items);
}

public bool IsItemSelected(int sectionIndex, int itemIndex)
{
if (VirtualView is null)
Expand Down
Loading