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

Commit

Permalink
[UWP] Fixes to Cell for ListView and CollectionView (#13277) fixes #1…
Browse files Browse the repository at this point in the history
…0473

* Update azure-pipelines.yml

* Fix #10473 using changes made by @gentledepp but not subject to a XF PR.  These have been tested and seem work solve the issue of the Cell not being disposed of as they are now reused rather than created from scratch.  I am only putting forward the PR.

* Changed the .yml file back to the current version not sure how or why it changed....

* Update azure-pipelines.yml

* Update azure-pipelines.yml

FIxed so that it's now reverted to the current live version of the file...

* Update azure-pipelines.yml

Co-authored-by: Rui Marinho <me@ruimarinho.net>
  • Loading branch information
CliffAgius and rmarinho committed Jan 15, 2021
1 parent c7f2090 commit 2f8fe84
Showing 1 changed file with 75 additions and 8 deletions.
83 changes: 75 additions & 8 deletions Xamarin.Forms.Platform.UAP/CellControl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,34 @@ public CellControl()

DataContextChanged += OnDataContextChanged;

Unloaded += (sender, args) =>
{
Cell?.SendDisappearing();
};
Loaded += OnLoaded;
Unloaded += OnUnloaded;

_propertyChangedHandler = OnCellPropertyChanged;
}

void OnLoaded(object sender, RoutedEventArgs e)
{
if (Cell == null)
return;

/// 🚀 subscribe topropertychanged
// make sure we do not subscribe twice (because this could happen in SetSource(Cell oldCell, Cell newCell))
Cell.PropertyChanged -= _propertyChangedHandler;
Cell.PropertyChanged += _propertyChangedHandler;
}

void OnUnloaded(object sender, RoutedEventArgs e)
{
if (Cell == null)
return;

Cell.SendDisappearing();
/// 🚀 unsubscribe from propertychanged
Cell.PropertyChanged -= _propertyChangedHandler;
}


public Cell Cell
{
get { return (Cell)GetValue(CellProperty); }
Expand Down Expand Up @@ -312,16 +332,49 @@ void SetCell(object newContext)
ListView lv = _listView.Value;
if (lv != null)
{
// 🚀 If there is an old cell, check if it was a group header
// we need this later to know whether we can recycle this cell
bool? wasGroupHeader = null;
var oldCell = Cell;
if (oldCell != null)
{
wasGroupHeader = oldCell.GetIsGroupHeader<ItemsView<Cell>, Cell>();
}

bool isGroupHeader = IsGroupHeader;
DataTemplate template = isGroupHeader ? lv.GroupHeaderTemplate : lv.ItemTemplate;
object bindingContext = newContext;

if (template is DataTemplateSelector)
bool sameTemplate = false;
if (template is DataTemplateSelector dataTemplateSelector)
{
template = ((DataTemplateSelector)template).SelectTemplate(bindingContext, lv);
template = dataTemplateSelector.SelectTemplate(bindingContext, lv);

// 🚀 If there exists an old cell, get its data template and check
// whether the new- and old template matches. In that case, we can recycle it
if (oldCell?.BindingContext != null)
{
DataTemplate oldTemplate = dataTemplateSelector.SelectTemplate(oldCell?.BindingContext, lv);
sameTemplate = oldTemplate == template;
}
}
// 🚀 if there is no datatemplateselector, we now verify if the old cell
// was a groupheader and whether the new one is as well.
// Again, this is only to verify we can reuse this cell
else if (wasGroupHeader.HasValue)
{
sameTemplate = wasGroupHeader == isGroupHeader;
}

// reuse cell
var canReuseCell = Cell != null && sameTemplate;

if (template != null)
// 🚀 If we can reuse the cell, just reuse it...
if (canReuseCell)
{
cell = Cell;
}
else if (template != null)
{
cell = template.CreateContent() as Cell;
}
Expand All @@ -345,7 +398,18 @@ void SetCell(object newContext)
cell.SetIsGroupHeader<ItemsView<Cell>, Cell>(isGroupHeader);
}

Cell = cell;
// 🚀 Only set the cell if it DID change
// Note: The cleanup (SendDisappearing(), etc.) is done by the Cell propertychanged callback so we do not need to do any cleanup ourselves.

if (Cell != cell)
Cell = cell;
// 🚀 even if the cell did not change, we **must** call SendDisappearing() and SendAppearing()
// because frameworks such as Reactive UI rely on this! (this.WhenActivated())
else if (Cell != null)
{
Cell.SendDisappearing();
Cell.SendAppearing();
}
}

void SetSource(Cell oldCell, Cell newCell)
Expand All @@ -364,10 +428,13 @@ void SetSource(Cell oldCell, Cell newCell)
UpdateFlowDirection(newCell);
SetupContextMenu();

// 🚀 make sure we do not subscribe twice (OnLoaded!)
newCell.PropertyChanged -= _propertyChangedHandler;
newCell.PropertyChanged += _propertyChangedHandler;
}
}


void SetupContextMenu()
{
if (CellContent == null || Cell == null)
Expand Down

0 comments on commit 2f8fe84

Please sign in to comment.