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

[CollectionView] UWP- Updating the ItemsLayout type should refresh the layout #10316

Closed
wants to merge 11 commits into from
29 changes: 13 additions & 16 deletions Xamarin.Forms.Platform.UAP/CollectionView/ItemContentControl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ namespace Xamarin.Forms.Platform.UWP
{
public class ItemContentControl : ContentControl
{
View _view;
IVisualElementRenderer _renderer;

public ItemContentControl()
Expand All @@ -17,7 +18,7 @@ public ItemContentControl()
}

public static readonly DependencyProperty FormsDataTemplateProperty = DependencyProperty.Register(
nameof(FormsDataTemplate), typeof(DataTemplate), typeof(ItemContentControl),
nameof(FormsDataTemplate), typeof(DataTemplate), typeof(ItemContentControl),
new PropertyMetadata(default(DataTemplate), FormsDataTemplateChanged));

static void FormsDataTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
Expand All @@ -38,7 +39,7 @@ public DataTemplate FormsDataTemplate
}

public static readonly DependencyProperty FormsDataContextProperty = DependencyProperty.Register(
nameof(FormsDataContext), typeof(object), typeof(ItemContentControl),
nameof(FormsDataContext), typeof(object), typeof(ItemContentControl),
new PropertyMetadata(default(object), FormsDataContextChanged));

static void FormsDataContextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
Expand Down Expand Up @@ -103,15 +104,11 @@ protected override void OnContentChanged(object oldContent, object newContent)
{
base.OnContentChanged(oldContent, newContent);

if (oldContent is FrameworkElement oldElement)
{
oldElement.Loaded -= ContentLoaded;
}
if (oldContent != null && _view != null)
_view.MeasureInvalidated -= OnViewMeasureInvalidated;

if (newContent is FrameworkElement newElement)
{
newElement.Loaded += ContentLoaded;
}
if (newContent != null && _view != null)
_view.MeasureInvalidated += OnViewMeasureInvalidated;
}

internal void Realize()
Expand All @@ -132,17 +129,17 @@ internal void Realize()
return;
}

var view = FormsDataTemplate.CreateContent(dataContext, container) as View;
view.BindingContext = dataContext;
_renderer = Platform.CreateRenderer(view);
Platform.SetRenderer(view, _renderer);
_view = FormsDataTemplate.CreateContent(dataContext, container) as View;
_view.BindingContext = dataContext;
_renderer = Platform.CreateRenderer(_view);
Platform.SetRenderer(_view, _renderer);

Content = _renderer.ContainerElement;

itemsView?.AddLogicalChild(view);
itemsView?.AddLogicalChild(_view);
}

void ContentLoaded(object sender, RoutedEventArgs e)
void OnViewMeasureInvalidated(object sender, EventArgs e)
{
InvalidateMeasure();
}
Expand Down
40 changes: 33 additions & 7 deletions Xamarin.Forms.Platform.UAP/CollectionView/ItemsViewRenderer.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
using System.Collections.Specialized;
using System.ComponentModel;
using System.Threading.Tasks;

using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.Foundation;

using Xamarin.Forms.Internals;

using UwpApp = Windows.UI.Xaml.Application;
using UwpDataTemplate = Windows.UI.Xaml.DataTemplate;
using UwpScrollBarVisibility = Windows.UI.Xaml.Controls.ScrollBarVisibility;
using UWPApp = Windows.UI.Xaml.Application;
using UWPDataTemplate = Windows.UI.Xaml.DataTemplate;

namespace Xamarin.Forms.Platform.UWP
{
Expand All @@ -27,8 +28,8 @@ public abstract class ItemsViewRenderer<TItemsView> : ViewRenderer<TItemsView, L
internal double _previousVerticalOffset;

protected ListViewBase ListViewBase { get; private set; }
protected UWPDataTemplate ViewTemplate => (UWPDataTemplate)UWPApp.Current.Resources["View"];
protected UWPDataTemplate ItemsViewTemplate => (UWPDataTemplate)UWPApp.Current.Resources["ItemsViewDefaultTemplate"];
protected UwpDataTemplate ViewTemplate => (UwpDataTemplate)UwpApp.Current.Resources["View"];
protected UwpDataTemplate ItemsViewTemplate => (UwpDataTemplate)UwpApp.Current.Resources["ItemsViewDefaultTemplate"];

protected ItemsViewRenderer()
{
Expand Down Expand Up @@ -392,6 +393,31 @@ protected virtual void UpdateEmptyView()
UpdateEmptyViewVisibility();
}

protected virtual void UpdateItemsLayout()
{
if (_scrollViewer != null)
_scrollViewer.ViewChanged -= OnScrollViewChanged;

if (ListViewBase != null)
{
ListViewBase.ItemsSource = null;
ListViewBase = null;
}

ListViewBase = SelectListViewBase();
ListViewBase.IsSynchronizedWithCurrentItem = false;

FindScrollViewer(ListViewBase);

SetNativeControl(ListViewBase);

UpdateItemTemplate();
UpdateItemsSource();
UpdateVerticalScrollBarVisibility();
UpdateHorizontalScrollBarVisibility();
UpdateEmptyView();
}

FrameworkElement RealizeEmptyViewTemplate(object bindingContext, DataTemplate emptyViewTemplate)
{
if (emptyViewTemplate == null)
Expand Down Expand Up @@ -478,4 +504,4 @@ void OnScrollViewChanged(object sender, ScrollViewerViewChangedEventArgs e)
HandleScroll(_scrollViewer);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using System;
using System.ComponentModel;

using Windows.UI.Xaml.Controls;

using UWPApp = Windows.UI.Xaml.Application;
using WListView = Windows.UI.Xaml.Controls.ListView;
using WScrollMode = Windows.UI.Xaml.Controls.ScrollMode;
Expand Down Expand Up @@ -43,6 +45,10 @@ protected override void OnElementPropertyChanged(object sender, PropertyChangedE
{
UpdateFooter();
}
else if (changedProperty.Is(StructuredItemsView.ItemsLayoutProperty))
{
UpdateItemsLayout();
}
}

protected override ListViewBase SelectListViewBase()
Expand All @@ -57,7 +63,7 @@ protected override ListViewBase SelectListViewBase()
return CreateHorizontalListView(listItemsLayout);
}

throw new NotImplementedException("The layout is not implemented");
throw new NotImplementedException("The layout is not implemented");
}

protected virtual void UpdateHeader()
Expand Down Expand Up @@ -211,7 +217,7 @@ static ListViewBase CreateVerticalListView(LinearItemsLayout listItemsLayout)

static ListViewBase CreateHorizontalListView(LinearItemsLayout listItemsLayout)
{
var horizontalListView = new WListView()
var horizontalListView = new FormsListView()
{
ItemsPanel = (ItemsPanelTemplate)UWPApp.Current.Resources["HorizontalListItemsPanel"],
ItemContainerStyle = GetHorizontalItemContainerStyle(listItemsLayout)
Expand All @@ -238,8 +244,8 @@ static WStyle GetItemContainerStyle(GridItemsLayout layout)
static WStyle GetVerticalItemContainerStyle(LinearItemsLayout layout)
{
var v = layout?.ItemSpacing ?? 0;
var margin = new WThickness(0, v, 0, v);
var margin = new WThickness(0, v, 0, v);

var style = new WStyle(typeof(ListViewItem));
style.Setters.Add(new WSetter(ListViewItem.MarginProperty, margin));
return style;
Expand Down