Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Framework / System / Windows / Controls / Primitives / ToolBarPanel.cs / 1305600 / ToolBarPanel.cs
//---------------------------------------------------------------------------- // // Copyright (C) Microsoft Corporation. All rights reserved. // //--------------------------------------------------------------------------- using MS.Internal; using MS.Internal.KnownBoxes; using MS.Utility; using System; using System.Collections; using System.Collections.Generic; using System.Collections.Specialized; using System.ComponentModel; using System.Diagnostics; using System.Windows.Controls.Primitives; using System.Windows.Data; using System.Windows.Media; using System.Windows.Threading; namespace System.Windows.Controls.Primitives { ////// ToolBarPanel is used to arrange children within the ToolBar. It is used in the ToolBar style as items host. /// // There is no need for this panel to be a StackPanel. public class ToolBarPanel : StackPanel { ////// Instantiates a new instance of this class. /// public ToolBarPanel() : base() { } #region Layout internal double MinLength { get; private set; } internal double MaxLength { get; private set; } private bool MeasureGeneratedItems(bool asNeededPass, Size constraint, bool horizontal, double maxExtent, ref Size panelDesiredSize, out double overflowExtent) { ToolBarOverflowPanel overflowPanel = ToolBarOverflowPanel; bool sendToOverflow = false; // Becomes true when the first AsNeeded does not fit bool hasOverflowItems = false; bool overflowNeedsInvalidation = false; overflowExtent = 0.0; UIElementCollection children = InternalChildren; int childrenCount = children.Count; int childrenIndex = 0; for (int i = 0; i < _generatedItemsCollection.Count; i++) { UIElement child = _generatedItemsCollection[i]; OverflowMode overflowMode = ToolBar.GetOverflowMode(child); bool asNeededMode = overflowMode == OverflowMode.AsNeeded; // MeasureGeneratedItems is called twice to do a complete measure. // The first pass measures Always and Never items -- items that // are guaranteed to be or not to be in the overflow menu. // The second pass measures AsNeeded items and determines whether // there is enough room for them in the main bar or if they should // be placed in the overflow menu. // Check here whether the overflow mode matches a mode we should be // examining in this pass. if (asNeededMode == asNeededPass) { DependencyObject visualParent = VisualTreeHelper.GetParent(child); // In non-Always overflow modes, measure for main bar placement. if ((overflowMode != OverflowMode.Always) && !sendToOverflow) { // Children may change their size depending on whether they are in the overflow // menu or not. Ensure that when we measure, we are using the main bar size. // If the item goes to overflow, this property will be updated later in this loop // when it is removed from the visual tree. ToolBar.SetIsOverflowItem(child, BooleanBoxes.FalseBox); child.Measure(constraint); Size childDesiredSize = child.DesiredSize; // If the child is an AsNeeded, check if it fits. If it doesn't then // this child and all subsequent AsNeeded children should be sent // to the overflow menu. if (asNeededMode) { double newExtent; if (horizontal) { newExtent = childDesiredSize.Width + panelDesiredSize.Width; } else { newExtent = childDesiredSize.Height + panelDesiredSize.Height; } if (DoubleUtil.GreaterThan(newExtent, maxExtent)) { // It doesn't fit, send to overflow sendToOverflow = true; } } // The child has been validated as belonging in the main bar. // Update the panel desired size dimensions, and ensure the child // is in the main bar's visual tree. if (!sendToOverflow) { if (horizontal) { panelDesiredSize.Width += childDesiredSize.Width; panelDesiredSize.Height = Math.Max(panelDesiredSize.Height, childDesiredSize.Height); } else { panelDesiredSize.Width = Math.Max(panelDesiredSize.Width, childDesiredSize.Width); panelDesiredSize.Height += childDesiredSize.Height; } if (visualParent != this) { if ((visualParent == overflowPanel) && (overflowPanel != null)) { overflowPanel.Children.Remove(child); } if (childrenIndex < childrenCount) { children.InsertInternal(childrenIndex, child); } else { children.AddInternal(child); } childrenCount++; } Debug.Assert(children[childrenIndex] == child, "InternalChildren is out of [....] with _generatedItemsCollection."); childrenIndex++; } } // The child should go to the overflow menu if ((overflowMode == OverflowMode.Always) || sendToOverflow) { hasOverflowItems = true; // If a child is in the overflow menu, we don't want to keep measuring. // However, we need to calculate the MaxLength as well as set the desired height // correctly. Thus, we will use the DesiredSize of the child. There is a problem // that can occur if the child changes size while in the overflow menu and // was recently displayed. It will be measure clean, yet its DesiredSize // will not be accurate for the MaxLength calculation. if (child.MeasureDirty) { // Set this temporarily in case the size is different while in the overflow area ToolBar.SetIsOverflowItem(child, BooleanBoxes.FalseBox); child.Measure(constraint); } // Even when in the overflow, we need two pieces of information: // 1. We need to continue to track the maximum size of the non-logical direction // (i.e. height in horizontal bars). This way, ToolBars with everything in // the overflow will still have some height. // 2. We want to track how much of the space we saved by placing the child in // the overflow menu. This is used to calculate MinLength and MaxLength. Size childDesiredSize = child.DesiredSize; if (horizontal) { overflowExtent += childDesiredSize.Width; panelDesiredSize.Height = Math.Max(panelDesiredSize.Height, childDesiredSize.Height); } else { overflowExtent += childDesiredSize.Height; panelDesiredSize.Width = Math.Max(panelDesiredSize.Width, childDesiredSize.Width); } // Set the flag to indicate that the child is in the overflow menu ToolBar.SetIsOverflowItem(child, BooleanBoxes.TrueBox); // If the child is in this panel's visual tree, remove it. if (visualParent == this) { Debug.Assert(children[childrenIndex] == child, "InternalChildren is out of [....] with _generatedItemsCollection."); children.RemoveNoVerify(child); childrenCount--; overflowNeedsInvalidation = true; } } } else { // We are not measure this child in this pass. Update the index into the // visual children collection. if ((childrenIndex < childrenCount) && (children[childrenIndex] == child)) { childrenIndex++; } } } // A child was added to the overflow panel, but since we don't add it // to the overflow panel's visual collection until that panel's measure // pass, we need to mark it as measure dirty. if (overflowNeedsInvalidation && (overflowPanel != null)) { overflowPanel.InvalidateMeasure(); } return hasOverflowItems; } ////// Measure the content and store the desired size of the content /// /// ///protected override Size MeasureOverride(Size constraint) { Size stackDesiredSize = new Size(); if (IsItemsHost) { Size layoutSlotSize = constraint; double maxExtent; double overflowExtent; bool horizontal = (Orientation == Orientation.Horizontal); if (horizontal) { layoutSlotSize.Width = Double.PositiveInfinity; maxExtent = constraint.Width; } else { layoutSlotSize.Height = Double.PositiveInfinity; maxExtent = constraint.Height; } // This first call will measure all of the non-AsNeeded elements (i.e. we know // whether they're going into the overflow or not. // overflowExtent will be the size of the Always elements, which is not actually // needed for subsequent calculations. bool hasAlwaysOverflowItems = MeasureGeneratedItems(/* asNeeded = */ false, layoutSlotSize, horizontal, maxExtent, ref stackDesiredSize, out overflowExtent); // At this point, the desired size is the minimum size of the ToolBar. MinLength = horizontal ? stackDesiredSize.Width : stackDesiredSize.Height; // This second call will measure all of the AsNeeded elements and place // them in the appropriate location. bool hasAsNeededOverflowItems = MeasureGeneratedItems(/* asNeeded = */ true, layoutSlotSize, horizontal, maxExtent, ref stackDesiredSize, out overflowExtent); // At this point, the desired size is complete. The desired size plus overflowExtent // is the maximum size of the ToolBar. MaxLength = (horizontal ? stackDesiredSize.Width : stackDesiredSize.Height) + overflowExtent; ToolBar toolbar = ToolBar; if (toolbar != null) { toolbar.SetValue(ToolBar.HasOverflowItemsPropertyKey, hasAlwaysOverflowItems || hasAsNeededOverflowItems); } } else { stackDesiredSize = base.MeasureOverride(constraint); } return stackDesiredSize; } /// /// Content arrangement. /// /// Arrange size protected override Size ArrangeOverride(Size arrangeSize) { UIElementCollection children = InternalChildren; bool fHorizontal = (Orientation == Orientation.Horizontal); Rect rcChild = new Rect(arrangeSize); double previousChildSize = 0.0d; // // Arrange and Position Children. // for (int i = 0, count = children.Count; i < count; ++i) { UIElement child = (UIElement)children[i]; if (fHorizontal) { rcChild.X += previousChildSize; previousChildSize = child.DesiredSize.Width; rcChild.Width = previousChildSize; rcChild.Height = Math.Max(arrangeSize.Height, child.DesiredSize.Height); } else { rcChild.Y += previousChildSize; previousChildSize = child.DesiredSize.Height; rcChild.Height = previousChildSize; rcChild.Width = Math.Max(arrangeSize.Width, child.DesiredSize.Width); } child.Arrange(rcChild); } return arrangeSize; } ////// ToolBarPanel sets bindings a on its Orientation property to its TemplatedParent if the /// property is not already set. /// internal override void OnPreApplyTemplate() { base.OnPreApplyTemplate(); if (TemplatedParent is ToolBar && !HasNonDefaultValue(OrientationProperty)) { Binding binding = new Binding(); binding.RelativeSource = RelativeSource.TemplatedParent; binding.Path = new PropertyPath(ToolBar.OrientationProperty); SetBinding(OrientationProperty, binding); } } #endregion #region Item Generation internal override void GenerateChildren() { base.GenerateChildren(); // This could re-enter InternalChildren, but after base.GenerateChildren, the collection // should be fully instantiated and ready to go. UIElementCollection children = InternalChildren; if (_generatedItemsCollection == null) { _generatedItemsCollection = new List(children.Count); } else { _generatedItemsCollection.Clear(); } ToolBarOverflowPanel overflowPanel = ToolBarOverflowPanel; if (overflowPanel != null) { overflowPanel.Children.Clear(); overflowPanel.InvalidateMeasure(); } int childrenCount = children.Count; for (int i = 0; i < childrenCount; i++) { UIElement child = children[i]; // Reset the overflow decision. This will be re-evaluated on the next measure // by ToolBarPanel.MeasureOverride. ToolBar.SetIsOverflowItem(child, BooleanBoxes.FalseBox); _generatedItemsCollection.Add(child); } } internal override void OnItemsChangedInternal(object sender, ItemsChangedEventArgs args) { switch (args.Action) { case NotifyCollectionChangedAction.Add: AddChildren(args.Position, args.ItemCount); break; case NotifyCollectionChangedAction.Remove: RemoveChildren(args.Position, args.ItemUICount); break; case NotifyCollectionChangedAction.Replace: ReplaceChildren(args.Position, args.ItemCount, args.ItemUICount); break; case NotifyCollectionChangedAction.Move: MoveChildren(args.OldPosition, args.Position, args.ItemUICount); break; case NotifyCollectionChangedAction.Reset: base.OnItemsChangedInternal(sender, args); break; } } private void AddChildren(GeneratorPosition pos, int itemCount) { IItemContainerGenerator generator = (IItemContainerGenerator)Generator; using (generator.StartAt(pos, GeneratorDirection.Forward)) { for (int i = 0; i < itemCount; i++) { UIElement e = generator.GenerateNext() as UIElement; if (e != null) { _generatedItemsCollection.Insert(pos.Index + 1 + i, e); generator.PrepareItemContainer(e); } } } } private void RemoveChild(UIElement child) { DependencyObject visualParent = VisualTreeHelper.GetParent(child); if (visualParent == this) { InternalChildren.RemoveInternal(child); } else { ToolBarOverflowPanel overflowPanel = ToolBarOverflowPanel; if ((visualParent == overflowPanel) && (overflowPanel != null)) { overflowPanel.Children.Remove(child); } } } private void RemoveChildren(GeneratorPosition pos, int containerCount) { for (int i = 0; i < containerCount; i++) { RemoveChild(_generatedItemsCollection[pos.Index + i]); } _generatedItemsCollection.RemoveRange(pos.Index, containerCount); } private void ReplaceChildren(GeneratorPosition pos, int itemCount, int containerCount) { Debug.Assert(itemCount == containerCount, "ToolBarPanel expects Replace to affect only realized containers"); IItemContainerGenerator generator = (IItemContainerGenerator)Generator; using (generator.StartAt(pos, GeneratorDirection.Forward, true)) { for (int i = 0; i < itemCount; i++) { bool isNewlyRealized; UIElement e = generator.GenerateNext(out isNewlyRealized) as UIElement; Debug.Assert(e != null && !isNewlyRealized, "ToolBarPanel expects Replace to affect only realized containers"); if (e != null && !isNewlyRealized) { RemoveChild(_generatedItemsCollection[pos.Index + i]); _generatedItemsCollection[pos.Index + i] = e; generator.PrepareItemContainer(e); } } } } private void MoveChildren(GeneratorPosition fromPos, GeneratorPosition toPos, int containerCount) { if (fromPos == toPos) return; IItemContainerGenerator generator = (IItemContainerGenerator)Generator; int toIndex = generator.IndexFromGeneratorPosition(toPos); UIElement[] elements = new UIElement[containerCount]; for (int i = 0; i < containerCount; i++) { UIElement child = _generatedItemsCollection[fromPos.Index + i]; RemoveChild(child); elements[i] = child; } _generatedItemsCollection.RemoveRange(fromPos.Index, containerCount); for (int i = 0; i < containerCount; i++) { _generatedItemsCollection.Insert(toIndex + i, elements[i]); } } #endregion #region Helpers private ToolBar ToolBar { get { return TemplatedParent as ToolBar; } } private ToolBarOverflowPanel ToolBarOverflowPanel { get { ToolBar tb = ToolBar; return tb == null ? null : tb.ToolBarOverflowPanel; } } // Accessed by ToolBarOverflowPanel internal List GeneratedItemsCollection { get { return _generatedItemsCollection; } } #endregion #region Data private List _generatedItemsCollection; #endregion } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. //---------------------------------------------------------------------------- // // Copyright (C) Microsoft Corporation. All rights reserved. // //--------------------------------------------------------------------------- using MS.Internal; using MS.Internal.KnownBoxes; using MS.Utility; using System; using System.Collections; using System.Collections.Generic; using System.Collections.Specialized; using System.ComponentModel; using System.Diagnostics; using System.Windows.Controls.Primitives; using System.Windows.Data; using System.Windows.Media; using System.Windows.Threading; namespace System.Windows.Controls.Primitives { /// /// ToolBarPanel is used to arrange children within the ToolBar. It is used in the ToolBar style as items host. /// // There is no need for this panel to be a StackPanel. public class ToolBarPanel : StackPanel { ////// Instantiates a new instance of this class. /// public ToolBarPanel() : base() { } #region Layout internal double MinLength { get; private set; } internal double MaxLength { get; private set; } private bool MeasureGeneratedItems(bool asNeededPass, Size constraint, bool horizontal, double maxExtent, ref Size panelDesiredSize, out double overflowExtent) { ToolBarOverflowPanel overflowPanel = ToolBarOverflowPanel; bool sendToOverflow = false; // Becomes true when the first AsNeeded does not fit bool hasOverflowItems = false; bool overflowNeedsInvalidation = false; overflowExtent = 0.0; UIElementCollection children = InternalChildren; int childrenCount = children.Count; int childrenIndex = 0; for (int i = 0; i < _generatedItemsCollection.Count; i++) { UIElement child = _generatedItemsCollection[i]; OverflowMode overflowMode = ToolBar.GetOverflowMode(child); bool asNeededMode = overflowMode == OverflowMode.AsNeeded; // MeasureGeneratedItems is called twice to do a complete measure. // The first pass measures Always and Never items -- items that // are guaranteed to be or not to be in the overflow menu. // The second pass measures AsNeeded items and determines whether // there is enough room for them in the main bar or if they should // be placed in the overflow menu. // Check here whether the overflow mode matches a mode we should be // examining in this pass. if (asNeededMode == asNeededPass) { DependencyObject visualParent = VisualTreeHelper.GetParent(child); // In non-Always overflow modes, measure for main bar placement. if ((overflowMode != OverflowMode.Always) && !sendToOverflow) { // Children may change their size depending on whether they are in the overflow // menu or not. Ensure that when we measure, we are using the main bar size. // If the item goes to overflow, this property will be updated later in this loop // when it is removed from the visual tree. ToolBar.SetIsOverflowItem(child, BooleanBoxes.FalseBox); child.Measure(constraint); Size childDesiredSize = child.DesiredSize; // If the child is an AsNeeded, check if it fits. If it doesn't then // this child and all subsequent AsNeeded children should be sent // to the overflow menu. if (asNeededMode) { double newExtent; if (horizontal) { newExtent = childDesiredSize.Width + panelDesiredSize.Width; } else { newExtent = childDesiredSize.Height + panelDesiredSize.Height; } if (DoubleUtil.GreaterThan(newExtent, maxExtent)) { // It doesn't fit, send to overflow sendToOverflow = true; } } // The child has been validated as belonging in the main bar. // Update the panel desired size dimensions, and ensure the child // is in the main bar's visual tree. if (!sendToOverflow) { if (horizontal) { panelDesiredSize.Width += childDesiredSize.Width; panelDesiredSize.Height = Math.Max(panelDesiredSize.Height, childDesiredSize.Height); } else { panelDesiredSize.Width = Math.Max(panelDesiredSize.Width, childDesiredSize.Width); panelDesiredSize.Height += childDesiredSize.Height; } if (visualParent != this) { if ((visualParent == overflowPanel) && (overflowPanel != null)) { overflowPanel.Children.Remove(child); } if (childrenIndex < childrenCount) { children.InsertInternal(childrenIndex, child); } else { children.AddInternal(child); } childrenCount++; } Debug.Assert(children[childrenIndex] == child, "InternalChildren is out of [....] with _generatedItemsCollection."); childrenIndex++; } } // The child should go to the overflow menu if ((overflowMode == OverflowMode.Always) || sendToOverflow) { hasOverflowItems = true; // If a child is in the overflow menu, we don't want to keep measuring. // However, we need to calculate the MaxLength as well as set the desired height // correctly. Thus, we will use the DesiredSize of the child. There is a problem // that can occur if the child changes size while in the overflow menu and // was recently displayed. It will be measure clean, yet its DesiredSize // will not be accurate for the MaxLength calculation. if (child.MeasureDirty) { // Set this temporarily in case the size is different while in the overflow area ToolBar.SetIsOverflowItem(child, BooleanBoxes.FalseBox); child.Measure(constraint); } // Even when in the overflow, we need two pieces of information: // 1. We need to continue to track the maximum size of the non-logical direction // (i.e. height in horizontal bars). This way, ToolBars with everything in // the overflow will still have some height. // 2. We want to track how much of the space we saved by placing the child in // the overflow menu. This is used to calculate MinLength and MaxLength. Size childDesiredSize = child.DesiredSize; if (horizontal) { overflowExtent += childDesiredSize.Width; panelDesiredSize.Height = Math.Max(panelDesiredSize.Height, childDesiredSize.Height); } else { overflowExtent += childDesiredSize.Height; panelDesiredSize.Width = Math.Max(panelDesiredSize.Width, childDesiredSize.Width); } // Set the flag to indicate that the child is in the overflow menu ToolBar.SetIsOverflowItem(child, BooleanBoxes.TrueBox); // If the child is in this panel's visual tree, remove it. if (visualParent == this) { Debug.Assert(children[childrenIndex] == child, "InternalChildren is out of [....] with _generatedItemsCollection."); children.RemoveNoVerify(child); childrenCount--; overflowNeedsInvalidation = true; } } } else { // We are not measure this child in this pass. Update the index into the // visual children collection. if ((childrenIndex < childrenCount) && (children[childrenIndex] == child)) { childrenIndex++; } } } // A child was added to the overflow panel, but since we don't add it // to the overflow panel's visual collection until that panel's measure // pass, we need to mark it as measure dirty. if (overflowNeedsInvalidation && (overflowPanel != null)) { overflowPanel.InvalidateMeasure(); } return hasOverflowItems; } ////// Measure the content and store the desired size of the content /// /// ///protected override Size MeasureOverride(Size constraint) { Size stackDesiredSize = new Size(); if (IsItemsHost) { Size layoutSlotSize = constraint; double maxExtent; double overflowExtent; bool horizontal = (Orientation == Orientation.Horizontal); if (horizontal) { layoutSlotSize.Width = Double.PositiveInfinity; maxExtent = constraint.Width; } else { layoutSlotSize.Height = Double.PositiveInfinity; maxExtent = constraint.Height; } // This first call will measure all of the non-AsNeeded elements (i.e. we know // whether they're going into the overflow or not. // overflowExtent will be the size of the Always elements, which is not actually // needed for subsequent calculations. bool hasAlwaysOverflowItems = MeasureGeneratedItems(/* asNeeded = */ false, layoutSlotSize, horizontal, maxExtent, ref stackDesiredSize, out overflowExtent); // At this point, the desired size is the minimum size of the ToolBar. MinLength = horizontal ? stackDesiredSize.Width : stackDesiredSize.Height; // This second call will measure all of the AsNeeded elements and place // them in the appropriate location. bool hasAsNeededOverflowItems = MeasureGeneratedItems(/* asNeeded = */ true, layoutSlotSize, horizontal, maxExtent, ref stackDesiredSize, out overflowExtent); // At this point, the desired size is complete. The desired size plus overflowExtent // is the maximum size of the ToolBar. MaxLength = (horizontal ? stackDesiredSize.Width : stackDesiredSize.Height) + overflowExtent; ToolBar toolbar = ToolBar; if (toolbar != null) { toolbar.SetValue(ToolBar.HasOverflowItemsPropertyKey, hasAlwaysOverflowItems || hasAsNeededOverflowItems); } } else { stackDesiredSize = base.MeasureOverride(constraint); } return stackDesiredSize; } /// /// Content arrangement. /// /// Arrange size protected override Size ArrangeOverride(Size arrangeSize) { UIElementCollection children = InternalChildren; bool fHorizontal = (Orientation == Orientation.Horizontal); Rect rcChild = new Rect(arrangeSize); double previousChildSize = 0.0d; // // Arrange and Position Children. // for (int i = 0, count = children.Count; i < count; ++i) { UIElement child = (UIElement)children[i]; if (fHorizontal) { rcChild.X += previousChildSize; previousChildSize = child.DesiredSize.Width; rcChild.Width = previousChildSize; rcChild.Height = Math.Max(arrangeSize.Height, child.DesiredSize.Height); } else { rcChild.Y += previousChildSize; previousChildSize = child.DesiredSize.Height; rcChild.Height = previousChildSize; rcChild.Width = Math.Max(arrangeSize.Width, child.DesiredSize.Width); } child.Arrange(rcChild); } return arrangeSize; } ////// ToolBarPanel sets bindings a on its Orientation property to its TemplatedParent if the /// property is not already set. /// internal override void OnPreApplyTemplate() { base.OnPreApplyTemplate(); if (TemplatedParent is ToolBar && !HasNonDefaultValue(OrientationProperty)) { Binding binding = new Binding(); binding.RelativeSource = RelativeSource.TemplatedParent; binding.Path = new PropertyPath(ToolBar.OrientationProperty); SetBinding(OrientationProperty, binding); } } #endregion #region Item Generation internal override void GenerateChildren() { base.GenerateChildren(); // This could re-enter InternalChildren, but after base.GenerateChildren, the collection // should be fully instantiated and ready to go. UIElementCollection children = InternalChildren; if (_generatedItemsCollection == null) { _generatedItemsCollection = new List(children.Count); } else { _generatedItemsCollection.Clear(); } ToolBarOverflowPanel overflowPanel = ToolBarOverflowPanel; if (overflowPanel != null) { overflowPanel.Children.Clear(); overflowPanel.InvalidateMeasure(); } int childrenCount = children.Count; for (int i = 0; i < childrenCount; i++) { UIElement child = children[i]; // Reset the overflow decision. This will be re-evaluated on the next measure // by ToolBarPanel.MeasureOverride. ToolBar.SetIsOverflowItem(child, BooleanBoxes.FalseBox); _generatedItemsCollection.Add(child); } } internal override void OnItemsChangedInternal(object sender, ItemsChangedEventArgs args) { switch (args.Action) { case NotifyCollectionChangedAction.Add: AddChildren(args.Position, args.ItemCount); break; case NotifyCollectionChangedAction.Remove: RemoveChildren(args.Position, args.ItemUICount); break; case NotifyCollectionChangedAction.Replace: ReplaceChildren(args.Position, args.ItemCount, args.ItemUICount); break; case NotifyCollectionChangedAction.Move: MoveChildren(args.OldPosition, args.Position, args.ItemUICount); break; case NotifyCollectionChangedAction.Reset: base.OnItemsChangedInternal(sender, args); break; } } private void AddChildren(GeneratorPosition pos, int itemCount) { IItemContainerGenerator generator = (IItemContainerGenerator)Generator; using (generator.StartAt(pos, GeneratorDirection.Forward)) { for (int i = 0; i < itemCount; i++) { UIElement e = generator.GenerateNext() as UIElement; if (e != null) { _generatedItemsCollection.Insert(pos.Index + 1 + i, e); generator.PrepareItemContainer(e); } } } } private void RemoveChild(UIElement child) { DependencyObject visualParent = VisualTreeHelper.GetParent(child); if (visualParent == this) { InternalChildren.RemoveInternal(child); } else { ToolBarOverflowPanel overflowPanel = ToolBarOverflowPanel; if ((visualParent == overflowPanel) && (overflowPanel != null)) { overflowPanel.Children.Remove(child); } } } private void RemoveChildren(GeneratorPosition pos, int containerCount) { for (int i = 0; i < containerCount; i++) { RemoveChild(_generatedItemsCollection[pos.Index + i]); } _generatedItemsCollection.RemoveRange(pos.Index, containerCount); } private void ReplaceChildren(GeneratorPosition pos, int itemCount, int containerCount) { Debug.Assert(itemCount == containerCount, "ToolBarPanel expects Replace to affect only realized containers"); IItemContainerGenerator generator = (IItemContainerGenerator)Generator; using (generator.StartAt(pos, GeneratorDirection.Forward, true)) { for (int i = 0; i < itemCount; i++) { bool isNewlyRealized; UIElement e = generator.GenerateNext(out isNewlyRealized) as UIElement; Debug.Assert(e != null && !isNewlyRealized, "ToolBarPanel expects Replace to affect only realized containers"); if (e != null && !isNewlyRealized) { RemoveChild(_generatedItemsCollection[pos.Index + i]); _generatedItemsCollection[pos.Index + i] = e; generator.PrepareItemContainer(e); } } } } private void MoveChildren(GeneratorPosition fromPos, GeneratorPosition toPos, int containerCount) { if (fromPos == toPos) return; IItemContainerGenerator generator = (IItemContainerGenerator)Generator; int toIndex = generator.IndexFromGeneratorPosition(toPos); UIElement[] elements = new UIElement[containerCount]; for (int i = 0; i < containerCount; i++) { UIElement child = _generatedItemsCollection[fromPos.Index + i]; RemoveChild(child); elements[i] = child; } _generatedItemsCollection.RemoveRange(fromPos.Index, containerCount); for (int i = 0; i < containerCount; i++) { _generatedItemsCollection.Insert(toIndex + i, elements[i]); } } #endregion #region Helpers private ToolBar ToolBar { get { return TemplatedParent as ToolBar; } } private ToolBarOverflowPanel ToolBarOverflowPanel { get { ToolBar tb = ToolBar; return tb == null ? null : tb.ToolBarOverflowPanel; } } // Accessed by ToolBarOverflowPanel internal List GeneratedItemsCollection { get { return _generatedItemsCollection; } } #endregion #region Data private List _generatedItemsCollection; #endregion } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- DateTimeValueSerializerContext.cs
- WebControl.cs
- DataGridPageChangedEventArgs.cs
- SafeCryptoHandles.cs
- EntityProxyTypeInfo.cs
- EntityDataSourceStatementEditor.cs
- EventSetter.cs
- ErrorStyle.cs
- WhileDesigner.xaml.cs
- WindowsStatusBar.cs
- XmlLoader.cs
- PageSettings.cs
- SqlTriggerContext.cs
- HTTPNotFoundHandler.cs
- WebBrowserUriTypeConverter.cs
- BitmapDownload.cs
- DocumentReferenceCollection.cs
- DataBindEngine.cs
- SerializationSectionGroup.cs
- TemplateBindingExtensionConverter.cs
- VisualStyleInformation.cs
- Lease.cs
- EventSourceCreationData.cs
- KnowledgeBase.cs
- PointHitTestResult.cs
- DataBoundControl.cs
- PathFigure.cs
- ManifestSignatureInformation.cs
- dataprotectionpermissionattribute.cs
- UnsafeNativeMethods.cs
- FormatConvertedBitmap.cs
- Visual3D.cs
- UserControlDesigner.cs
- TableAutomationPeer.cs
- ComponentManagerBroker.cs
- MSAANativeProvider.cs
- CodeParameterDeclarationExpression.cs
- IMembershipProvider.cs
- AnimationException.cs
- AuthenticationModuleElement.cs
- HttpFileCollection.cs
- SamlAttribute.cs
- _ShellExpression.cs
- ResourcePermissionBase.cs
- ObjectContext.cs
- CommentEmitter.cs
- PermissionRequestEvidence.cs
- BackStopAuthenticationModule.cs
- TextServicesDisplayAttribute.cs
- GetTokenRequest.cs
- DataTemplate.cs
- SortFieldComparer.cs
- BitmapPalette.cs
- OnOperation.cs
- ColorTransformHelper.cs
- SByteConverter.cs
- IndexedEnumerable.cs
- SharedUtils.cs
- SmiXetterAccessMap.cs
- EventOpcode.cs
- XamlPathDataSerializer.cs
- ControlType.cs
- ZoomPercentageConverter.cs
- BaseServiceProvider.cs
- NetDispatcherFaultException.cs
- XmlSchemaGroup.cs
- TextStore.cs
- filewebresponse.cs
- WebPartsPersonalizationAuthorization.cs
- AxHost.cs
- SystemUdpStatistics.cs
- SchemaElementDecl.cs
- sqlmetadatafactory.cs
- HttpApplicationFactory.cs
- InputLanguage.cs
- NameNode.cs
- BindingGraph.cs
- IncrementalCompileAnalyzer.cs
- ObjectDataSourceStatusEventArgs.cs
- QueryFunctions.cs
- IItemProperties.cs
- SecurityHeaderElementInferenceEngine.cs
- WebPart.cs
- Lease.cs
- RegistryKey.cs
- Vector3DValueSerializer.cs
- Vertex.cs
- NullEntityWrapper.cs
- Rect.cs
- TemplateXamlParser.cs
- MethodAccessException.cs
- DataTableMappingCollection.cs
- GenericTypeParameterConverter.cs
- ActivityBuilderXamlWriter.cs
- SelectionEditor.cs
- FocusWithinProperty.cs
- QueueAccessMode.cs
- PopupEventArgs.cs
- KernelTypeValidation.cs
- StringArrayConverter.cs