/// protected override List<AutomationPeer> GetChildrenCore() { // To avoid the situation on legacy systems which may not have new unmanaged core. with this change with old unmanaged core // the behavior would be same as earlier. if (IsVirtualized) return base.GetChildrenCore(); else { ItemsControl owner = (ItemsControl)Owner; ItemCollection items = owner.Items; List<AutomationPeer> children = null; ItemPeersStorage<ItemAutomationPeer> oldChildren = ItemPeers; //cache the old ones for possible reuse ItemPeers = new ItemPeersStorage<ItemAutomationPeer>(); if (items.Count > 0) { children = new List<AutomationPeer>(items.Count); for (int i = 0; i < items.Count; i++) { TreeViewItem treeViewItem = owner.ItemContainerGenerator.ContainerFromIndex(i) as TreeViewItem; if (treeViewItem != null) { ItemAutomationPeer peer = oldChildren[items[i]]; if (peer == null) peer = CreateItemAutomationPeer(items[i]); // perform hookup so the events sourced from wrapper peer are fired as if from the data item if (peer != null) { AutomationPeer wrapperPeer = peer.GetWrapperPeer(); if(wrapperPeer != null) { wrapperPeer.EventsSource = peer; } } // Not to add same Item again if (ItemPeers[items[i]] == null) { children.Add(peer); ItemPeers[items[i]] = peer; } } } return children; } } return null; }
/// protected override List<AutomationPeer> GetChildrenCore() { List<AutomationPeer> children = null; ItemPeersStorage<ItemAutomationPeer> oldChildren = ItemPeers; //cache the old ones for possible reuse ItemPeers = new ItemPeersStorage<ItemAutomationPeer>(); TreeViewItem owner = Owner as TreeViewItem; if (owner != null) { iterate(this, owner, (IteratorCallback)delegate(AutomationPeer peer) { if (children == null) children = new List<AutomationPeer>(); children.Add(peer); return (false); }, ItemPeers, oldChildren); } return children; }
/// protected override List<AutomationPeer> GetChildrenCore() { GroupItem owner = (GroupItem)Owner; ItemsControl itemsControl = ItemsControl.ItemsControlFromItemContainer(Owner); if (itemsControl != null) { ItemsControlAutomationPeer itemsControlAP = itemsControl.CreateAutomationPeer() as ItemsControlAutomationPeer; if (itemsControlAP != null) { ItemContainerGenerator generator = owner.Generator; if (generator != null) { IList items = generator.Items; List<AutomationPeer> children = new List<AutomationPeer>(items.Count); ItemPeersStorage<ItemAutomationPeer> oldChildren = _dataChildren; //cache the old ones for possible reuse _dataChildren = new ItemPeersStorage<ItemAutomationPeer>(); if (items.Count > 0) { foreach (object item in items) { CollectionViewGroup cvg = item as CollectionViewGroup; if (cvg != null) { GroupItem groupItem = generator.ContainerFromItem(item) as GroupItem; if (groupItem != null) { GroupItemAutomationPeer peer = groupItem.CreateAutomationPeer() as GroupItemAutomationPeer; if (peer != null) children.Add(peer); } } else { //try to reuse old peer if it exists ItemAutomationPeer peer = oldChildren[item]; //no old peer - create new one if (peer == null) peer = itemsControlAP.CreateItemAutomationPeerInternal(item); //perform hookup so the events sourced from wrapper peer are fired as if from the data item if (peer != null) { AutomationPeer wrapperPeer = peer.GetWrapperPeer(); if (wrapperPeer != null) { wrapperPeer.EventsSource = peer; if (peer.ChildrenValid && peer.Children == null && this.AncestorsInvalid) { peer.AncestorsInvalid = true; wrapperPeer.AncestorsInvalid = true; } } } //protection from indistinguishable items - for example, 2 strings with same value //this scenario does not work in ItemsControl however is not checked for. if (_dataChildren[item] == null) { children.Add(peer); _dataChildren[item] = peer; // Update ItemsControl cache too // ItemPeers needs to be updated because used in Selector and other ItemsControl subclasses to access item peers directly if (itemsControlAP.ItemPeers[item] == null) { itemsControlAP.ItemPeers[item] = peer; } } } } return children; } } } } return null; }
///<summary> /// Creates Children peers. /// /// GetChildrenCore and FindItemByProperty are almost straight copies of the /// ItemControlAutomationPeer code; however since DataGridColumHeaderPresenter /// returns the Column.Header's as the items some specialized code was needed to /// create and store peers. ///</summary> protected override List<AutomationPeer> GetChildrenCore() { List<AutomationPeer> children = null; ItemPeersStorage<ItemAutomationPeer> oldChildren = ItemPeers; //cache the old ones for possible reuse ItemPeers = new ItemPeersStorage<ItemAutomationPeer>(); ItemsControl owner = (ItemsControl)Owner; if (OwningDataGrid.Columns.Count > 0) { IList childItems = null; Panel itemHost = owner.ItemsHost; // To avoid the situation on legacy systems which may not have new unmanaged core. this check with old unmanaged core // ensures the older behavior as ItemContainer pattern won't be available. if (ItemContainerPatternIdentifiers.Pattern != null) { if (itemHost == null) return null; childItems = itemHost.Children; } else { childItems = OwningDataGrid.Columns; } children = new List<AutomationPeer>(childItems.Count); foreach (object item in childItems) { DataGridColumn dataItem; if (item is DataGridColumnHeader) { dataItem = ((DataGridColumnHeader) item).Column; } else { dataItem = item as DataGridColumn; } // try to reuse old peer if it exists either in Current AT or in WeakRefStorage of Peers being sent to Client ItemAutomationPeer peer = oldChildren[dataItem]; if (peer == null) { peer = GetPeerFromWeakRefStorage(dataItem); // As cached peer is getting used it must be invalidated. if (peer != null) { peer.AncestorsInvalid = false; peer.ChildrenValid = false; } } if (peer == null) { peer = CreateItemAutomationPeer(dataItem); } // perform hookup so the events sourced from wrapper peer are fired as if from the data item if (peer != null) { AutomationPeer wrapperPeer = peer.GetWrapperPeer(); if (wrapperPeer != null) { wrapperPeer.EventsSource = peer; } } // protection from indistinguishable items - for example, 2 strings with same value // this scenario does not work in ItemsControl however is not checked for. if (ItemPeers[dataItem] == null) { children.Add(peer); ItemPeers[dataItem] = peer; } } return children; } return null; }
// private static bool iterate(TreeViewItemAutomationPeer logicalParentAp, DependencyObject parent, IteratorCallback callback, ItemPeersStorage<ItemAutomationPeer> dataChildren, ItemPeersStorage<ItemAutomationPeer> oldChildren) { bool done = false; if (parent != null) { AutomationPeer peer = null; int count = VisualTreeHelper.GetChildrenCount(parent); for (int i = 0; i < count && !done; i++) { DependencyObject child = VisualTreeHelper.GetChild(parent, i); if (child != null && child is UIElement) { if (child is TreeViewItem) { object dataItem = (child as UIElement) != null ? (logicalParentAp.Owner as ItemsControl).GetItemOrContainerFromContainer(child as UIElement) : child; peer = oldChildren[dataItem]; if (peer == null) { peer = logicalParentAp.GetPeerFromWeakRefStorage(dataItem); if (peer != null) { // As cached peer is getting used it must be invalidated. peer.AncestorsInvalid = false; peer.ChildrenValid = false; } } if (peer == null) { peer = logicalParentAp.CreateItemAutomationPeer(dataItem); } //perform hookup so the events sourced from wrapper peer are fired as if from the data item if (peer != null) { AutomationPeer wrapperPeer = (peer as ItemAutomationPeer).GetWrapperPeer(); if (wrapperPeer != null) { wrapperPeer.EventsSource = peer; } if (dataChildren[dataItem] == null && peer is ItemAutomationPeer) { callback(peer); dataChildren[dataItem] = peer as ItemAutomationPeer; } } } else { peer = CreatePeerForElement((UIElement)child); if (peer != null) done = callback(peer); } if(peer == null) done = iterate(logicalParentAp, child, callback, dataChildren, oldChildren); } else { done = iterate(logicalParentAp, child, callback, dataChildren, oldChildren); } } } return done; }
/// <summary> /// Realized Columns only /// </summary> /// <returns></returns> internal List<AutomationPeer> GetCellItemPeers() { List<AutomationPeer> children = null; ItemPeersStorage<DataGridCellItemAutomationPeer> newChildren = new ItemPeersStorage<DataGridCellItemAutomationPeer>(); IList childItems = null; bool usingItemsHost = false; DataGridRow row = GetWrapper() as DataGridRow; if (row != null) { if (row.CellsPresenter != null) { Panel itemHost = row.CellsPresenter.ItemsHost; if (itemHost != null) { childItems = itemHost.Children; usingItemsHost = true; } } } if (!usingItemsHost) { childItems = OwningDataGrid.Columns; } if (childItems != null) { children = new List<AutomationPeer>(childItems.Count); foreach (object childItem in childItems) { DataGridColumn column = null; if (usingItemsHost) { column = (childItem as DataGridCell).Column; } else { column = childItem as DataGridColumn; } if (column != null) { DataGridCellItemAutomationPeer peer = GetOrCreateCellItemPeer(column,/*addParentInfo*/ false ); children.Add(peer); newChildren[column] = peer; } } } // Cache children for reuse CellItemPeers = newChildren; return children; }