public void UpdatePin(UIElement element, bool addPin) { var parent = CachedVisualTreeHelpers.GetParent(element); DependencyObject child = element; while (parent != null) { if (parent is ItemsRepeater repeater) { var virtInfo = ItemsRepeater.GetVirtualizationInfo((UIElement)child); if (virtInfo.IsRealized) { if (addPin) { virtInfo.AddPin(); } else if (virtInfo.IsPinned) { if (virtInfo.RemovePin() == 0) { // ElementFactory is invoked during the measure pass. // We will clear the element then. repeater.InvalidateMeasure(); } } } } child = parent; parent = CachedVisualTreeHelpers.GetParent(child); } }
private void OnHideAnimationCompleted(ElementAnimator sender, UIElement element) { if (CachedVisualTreeHelpers.GetParent(element) == m_owner) { m_owner.ViewManager.ClearElementToElementFactory(element); // Invalidate arrange so that repeater can arrange this element off-screen. m_owner.InvalidateArrange(); } }
private void UpdateFocusedElement() { UIElement focusedElement = null; // auto child = winrt::FocusManager::GetFocusedElement().as<winrt::DependencyObject>(); var child = Keyboard.FocusedElement as DependencyObject; if (child != null) { var parent = CachedVisualTreeHelpers.GetParent(child); var owner = m_owner; // Find out if the focused element belongs to one of our direct // children. while (parent != null) { var repeater = parent as ItemsRepeater; if (repeater != null) { var element = child as UIElement; if (repeater == owner && ItemsRepeater.GetVirtualizationInfo(element).IsRealized) { focusedElement = element; } break; } child = parent; parent = CachedVisualTreeHelpers.GetParent(child); } } // If the focused element has changed, // we need to unpin the old one and pin the new one. if (m_lastFocusedElement != focusedElement) { if (m_lastFocusedElement != null) { UpdatePin(m_lastFocusedElement, false /* addPin */); } if (focusedElement != null) { UpdatePin(focusedElement, true /* addPin */); } m_lastFocusedElement = (focusedElement); } }
private UIElement GetElementFromElementFactory(int index) { // The view generator is the provider of last resort. var data = m_owner.ItemsSourceView.GetAt(index); UIElement initElement() { var providedElementFactory = m_owner.ItemTemplateShim; if (providedElementFactory == null) { if (data is UIElement dataAsElement) { return(dataAsElement); } } IElementFactoryShim initElementFactory() { if (providedElementFactory == null) { var factory = XamlReader.Parse("<DataTemplate xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'><TextBlock Text='{Binding}'/></DataTemplate>") as DataTemplate; m_owner.ItemTemplate = factory; return(m_owner.ItemTemplateShim); } return(providedElementFactory); } var elementFactory = initElementFactory(); ElementFactoryGetArgs initArgs() { if (m_ElementFactoryGetArgs == null) { m_ElementFactoryGetArgs = new ElementFactoryGetArgs(); } return(m_ElementFactoryGetArgs); } var args = initArgs(); try { args.Data = data; args.Parent = m_owner; args.Index = index; return(elementFactory.GetElement(args)); } finally { args.Data = null; args.Parent = null; } } var element = initElement(); var virtInfo = ItemsRepeater.TryGetVirtualizationInfo(element); if (virtInfo == null) { virtInfo = ItemsRepeater.CreateAndInitializeVirtualizationInfo(element); } else { // View obtained from ElementFactory already has a VirtualizationInfo attached to it // which means that the element has been recycled and not created from scratch. } if (data != element) { if (element is FrameworkElement elementAsFE) { // Set data context only if no x:Bind was used. ie. No data template component on the root. // If the passed in data is a UIElement and is different from the element returned by // the template factory then we need to propagate the DataContext. // Otherwise just set the DataContext on the element as the data. object initElementDataContext() { if (data is FrameworkElement dataAsElement) { var dataDataContext = dataAsElement.DataContext; if (dataDataContext != null) { return(dataDataContext); } } return(data); } var elementDataContext = initElementDataContext(); elementAsFE.DataContext = elementDataContext; } else { Debug.Assert(false, "Element returned by factory is not a FrameworkElement!"); } } virtInfo.MoveOwnershipToLayoutFromElementFactory( index, /* uniqueId: */ m_owner.ItemsSourceView.HasKeyIndexMapping ? m_owner.ItemsSourceView.KeyFromIndex(index) : string.Empty); // The view generator is the only provider that prepares the element. var repeater = m_owner; // Add the element to the children collection here before raising OnElementPrepared so // that handlers can walk up the tree in case they want to find their IndexPath in the // nested case. var children = repeater.Children; if (CachedVisualTreeHelpers.GetParent(element) != repeater) { children.Add(element); } repeater.AnimationManager.OnElementPrepared(element); repeater.OnElementPrepared(element, index); // Update realized indices m_firstRealizedElementIndexHeldByLayout = Math.Min(m_firstRealizedElementIndexHeldByLayout, index); m_lastRealizedElementIndexHeldByLayout = Math.Max(m_lastRealizedElementIndexHeldByLayout, index); return(element); }
private UIElement GetElementFromElementFactory(int index) { // The view generator is the provider of last resort. var data = m_owner.ItemsSourceView.GetAt(index); var itemTemplateFactory = m_owner.ItemTemplateShim; UIElement element = null; bool itemsSourceContainsElements = false; if (itemTemplateFactory == null) { element = data as UIElement; // No item template provided and ItemsSource contains objects derived from UIElement. // In this case, just use the data directly as elements. itemsSourceContainsElements = element != null; } if (element == null) { if (itemTemplateFactory == null) { // If no ItemTemplate was provided, use a default var factory = XamlReader.Parse("<DataTemplate xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'><TextBlock Text='{Binding}'/></DataTemplate>") as DataTemplate; m_owner.ItemTemplate = factory; itemTemplateFactory = m_owner.ItemTemplateShim; } if (m_ElementFactoryGetArgs == null) { // Create one. m_ElementFactoryGetArgs = new ElementFactoryGetArgs(); } var args = m_ElementFactoryGetArgs; args.Data = data; args.Parent = m_owner; args.Index = index; element = itemTemplateFactory.GetElement(args); args.Data = null; args.Parent = null; } var virtInfo = ItemsRepeater.TryGetVirtualizationInfo(element); if (virtInfo == null) { virtInfo = ItemsRepeater.CreateAndInitializeVirtualizationInfo(element); } else { // View obtained from ElementFactory already has a VirtualizationInfo attached to it // which means that the element has been recycled and not created from scratch. } if (!itemsSourceContainsElements) { // Set data context only if no x:Bind was used. ie. No data template component on the root. var elementAsFE = element as FrameworkElement; elementAsFE.DataContext = data; } virtInfo.MoveOwnershipToLayoutFromElementFactory( index, /* uniqueId: */ m_owner.ItemsSourceView.HasKeyIndexMapping ? m_owner.ItemsSourceView.KeyFromIndex(index) : string.Empty); // The view generator is the only provider that prepares the element. var repeater = m_owner; // Add the element to the children collection here before raising OnElementPrepared so // that handlers can walk up the tree in case they want to find their IndexPath in the // nested case. var children = repeater.Children; if (CachedVisualTreeHelpers.GetParent(element) != repeater) { children.Add(element); } repeater.AnimationManager.OnElementPrepared(element); repeater.OnElementPrepared(element, index); // Update realized indices m_firstRealizedElementIndexHeldByLayout = Math.Min(m_firstRealizedElementIndexHeldByLayout, index); m_lastRealizedElementIndexHeldByLayout = Math.Max(m_lastRealizedElementIndexHeldByLayout, index); return(element); }