// We need to clear the datacontext to prevent crashes from happening, // however we only do that if we were the ones setting it. // That is when one of the following is the case (numbering taken from line ~642): // 1.2 No ItemTemplate, data is not a UIElement // 2.1 ItemTemplate, data is not FrameworkElement // 2.2.2 Itemtemplate, data is FrameworkElement, ElementFactory returned Element different to data // // In all of those three cases, we the ItemTemplateShim is NOT null. // Luckily when we create the items, we store whether we were the once setting the DataContext. public void ClearElementToElementFactory(UIElement element) { m_owner.OnElementClearing(element); var virtInfo = ItemsRepeater.GetVirtualizationInfo(element); virtInfo.MoveOwnershipToElementFactory(); // During creation of this object, we were the one setting the DataContext, so clear it now. if (virtInfo.MustClearDataContext) { if (element is FrameworkElement elementAsFE) { elementAsFE.DataContext = null; } } if (m_owner.ItemTemplateShim != null) { if (m_ElementFactoryRecycleArgs == null) { // Create one. m_ElementFactoryRecycleArgs = new ElementFactoryRecycleArgs(); } var context = m_ElementFactoryRecycleArgs; context.Element = element; context.Parent = m_owner; m_owner.ItemTemplateShim.RecycleElement(context); context.Element = null; context.Parent = null; } else { // No ItemTemplate to recycle to, remove the element from the children collection. var children = m_owner.Children; int childIndex = 0; bool found = children.IndexOf(element, out childIndex); if (!found) { throw new Exception("ItemsRepeater's child not found in its Children collection."); } children.RemoveAt(childIndex); } if (m_lastFocusedElement == element) { // Focused element is going away. Remove the tracked last focused element // and pick a reasonable next focus if we can find one within the layout // realized elements. int clearedIndex = virtInfo.Index; MoveFocusFromClearedIndex(clearedIndex); } }
void UnlinkElementFromParent(ElementFactoryRecycleArgs args) { // We want to unlink the containers from the parent repeater // in case we are required to move it to a different repeater. if (args.Parent is Panel panel) { var children = panel.Children; int childIndex = 0; if (children.IndexOf(args.Element, out childIndex)) { children.RemoveAt(childIndex); } } }
public void RecycleElement(ElementFactoryRecycleArgs args) { var element = args.Element; DataTemplate selectedTemplate = Template ?? element.GetValue(RecyclePool.OriginTemplateProperty) as DataTemplate; var recyclePool = RecyclePool.GetPoolInstance(selectedTemplate); if (recyclePool == null) { // No Recycle pool in the template, create one. recyclePool = new RecyclePool(); RecyclePool.SetPoolInstance(selectedTemplate, recyclePool); } recyclePool.PutElement(args.Element, string.Empty /* key */, args.Parent); }
protected override void RecycleElementCore(ElementFactoryRecycleArgs args) { if (m_itemTemplateWrapper != null) { m_itemTemplateWrapper.RecycleElement(args); } else { // We want to unlink the containers from the parent repeater // in case we are required to move it to a different repeater. if (args.Parent is Panel panel) { var children = panel.Children; int childIndex = 0; if (children.IndexOf(args.Element, out childIndex)) { children.RemoveAt(childIndex); } } } }
protected override void RecycleElementCore(ElementFactoryRecycleArgs args) { if (args.Element is { } element) { if (element is NavigationViewItem nvi) { var nviImpl = nvi; // Check whether we wrapped the element in a NavigationViewItem ourselves. // If yes, we are responsible for recycling it. if (nviImpl.CreatedByNavigationViewItemsFactory) { nviImpl.CreatedByNavigationViewItemsFactory = false; UnlinkElementFromParent(args); args.Element = null; // Retain the NVI that we created for future re-use navigationViewItemPool.Add(nvi); // Retrieve the proper element that requires recycling for a user defined item template // and update the args correspondingly if (m_itemTemplateWrapper != null) { // TODO: Retrieve the element and add to the args } } } // Do not recycle SettingsItem bool isSettingsItem = m_settingsItem != null && m_settingsItem == args.Element; if (m_itemTemplateWrapper != null && !isSettingsItem) { m_itemTemplateWrapper.RecycleElement(args); } else { UnlinkElementFromParent(args); } } }
protected virtual void RecycleElementCore(ElementFactoryRecycleArgs args) { throw new NotImplementedException(); }
public void RecycleElement(ElementFactoryRecycleArgs args) { RecycleElementCore(args); }
// Retrieve the element that will be displayed for a specific data item. // If the resolved element is not derived from NavigationViewItemBase, wrap in a NavigationViewItem before returning. protected override UIElement GetElementCore(ElementFactoryGetArgs args) { object newContent; { object init() { if (m_itemTemplateWrapper != null) { return(m_itemTemplateWrapper.GetElement(args)); } return(args.Data); } newContent = init(); } // Element is already of expected type, just return it if (newContent is NavigationViewItemBase newItem) { return(newItem); } // Get or create a wrapping container for the data NavigationViewItem nvi; { nvi = init(); NavigationViewItem init() { if (navigationViewItemPool.Count > 0) { var nvi = navigationViewItemPool.Last(); navigationViewItemPool.RemoveLast(); return(nvi); } return(new NavigationViewItem()); } } var nviImpl = nvi; nviImpl.CreatedByNavigationViewItemsFactory = true; // If a user provided item template exists, just pass the template and data down to the ContentPresenter of the NavigationViewItem if (m_itemTemplateWrapper != null) { if (m_itemTemplateWrapper is ItemTemplateWrapper itemTemplateWrapper) { // Recycle newContent var tempArgs = new ElementFactoryRecycleArgs(); tempArgs.Element = newContent as UIElement; m_itemTemplateWrapper.RecycleElement(tempArgs); nviImpl.Content = args.Data; nviImpl.ContentTemplate = itemTemplateWrapper.Template; nviImpl.ContentTemplateSelector = itemTemplateWrapper.TemplateSelector; return(nviImpl); } } nviImpl.Content = newContent; return(nviImpl); }
protected override void RecycleElementCore(ElementFactoryRecycleArgs args) { }
protected abstract void RecycleElementCore(ElementFactoryRecycleArgs args);