public void Bind(DataTemplate template, object bindingContext, ItemsView itemsView) { var oldElement = VisualElementRenderer?.Element; // Run this through the extension method in case it's really a DataTemplateSelector var itemTemplate = template.SelectDataTemplate(bindingContext, itemsView); if (itemTemplate != _currentTemplate) { // Remove the old view, if it exists if (oldElement != null) { oldElement.MeasureInvalidated -= MeasureInvalidated; itemsView.RemoveLogicalChild(oldElement); ClearSubviews(); _size = Size.Zero; } // Create the content and renderer for the view var view = itemTemplate.CreateContent() as View; // Set the binding context _before_ we create the renderer; that way, it's available during OnElementChanged view.BindingContext = bindingContext; var renderer = TemplateHelpers.CreateRenderer(view); SetRenderer(renderer); // And make the new Element a "child" of the ItemsView // We deliberately do this _after_ setting the binding context for the new element; // if we do it before, the element briefly inherits the ItemsView's bindingcontext and we // emit a bunch of needless binding errors itemsView.AddLogicalChild(view); } else { // Same template, different data var currentElement = VisualElementRenderer?.Element; if (currentElement != null) { currentElement.BindingContext = bindingContext; } } _currentTemplate = itemTemplate; }
internal void UpdateView(object view, DataTemplate viewTemplate, ref UIView uiView, ref VisualElement formsElement) { // Is view set on the ItemsView? if (view == null) { if (formsElement != null) { Platform.GetRenderer(formsElement)?.DisposeRendererAndChildren(); } uiView?.Dispose(); uiView = null; formsElement = null; } else { // Create the native renderer for the view, and keep the actual Forms element (if any) // around for updating the layout later (uiView, formsElement) = TemplateHelpers.RealizeView(view, viewTemplate, ItemsView); } }