public static (UIView NativeView, VisualElement FormsElement) RealizeView(object view, DataTemplate viewTemplate, ItemsView itemsView) { if (viewTemplate != null) { // Run this through the extension method in case it's really a DataTemplateSelector viewTemplate = viewTemplate.SelectDataTemplate(view, itemsView); // We have a template; turn it into a Forms view var templateElement = viewTemplate.CreateContent() as View; // Make sure the Visual property is available when the renderer is created PropertyPropagationExtensions.PropagatePropertyChanged(null, templateElement, itemsView); var renderer = GetHandler(templateElement, itemsView.FindMauiContext()); var element = renderer.VirtualView as VisualElement; // and set the view as its BindingContext element.BindingContext = view; return((UIView)renderer.NativeView, element); } if (view is View formsView) { // Make sure the Visual property is available when the renderer is created PropertyPropagationExtensions.PropagatePropertyChanged(null, formsView, itemsView); // No template, and the EmptyView is a Forms view; use that var renderer = GetHandler(formsView, itemsView.FindMauiContext()); var element = renderer.VirtualView as VisualElement; return((UIView)renderer.NativeView, element); } return(new UILabel { TextAlignment = UITextAlignment.Center, Text = $"{view}" }, null); }
public void Bind(DataTemplate template, object bindingContext, ItemsView itemsView) { var oldElement = PlatformHandler?.VirtualView as View; // 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; oldElement.BindingContext = null; 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.GetHandler(view, itemsView.FindMauiContext()); 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); // Prevents the use of default color when there are VisualStateManager with Selected state setting the background color // First we check whether the cell has the default selected background color; if it does, then we should check // to see if the cell content is the VSM to set a selected color if (SelectedBackgroundView.BackgroundColor == Maui.Platform.ColorExtensions.Gray && IsUsingVSMForSelectionColor(view)) { SelectedBackgroundView = new UIView { BackgroundColor = UIColor.Clear }; } } else { // Same template if (oldElement != null) { if (oldElement.BindingContext == null || !(oldElement.BindingContext.Equals(bindingContext))) { // If the data is different, update it // Unhook the MeasureInvalidated handler, otherwise it'll fire for every invalidation during the // BindingContext change oldElement.MeasureInvalidated -= MeasureInvalidated; oldElement.BindingContext = bindingContext; oldElement.MeasureInvalidated += MeasureInvalidated; UpdateCellSize(); } } } CurrentTemplate = itemTemplate; }
static INativeViewHandler CreateHandler(View view, ItemsView itemsView) => TemplateHelpers.GetHandler(view, itemsView.FindMauiContext());