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
- ToolStripPanelRenderEventArgs.cs
- IOThreadScheduler.cs
- DocumentApplication.cs
- GridViewItemAutomationPeer.cs
- ToolStrip.cs
- WizardPanelChangingEventArgs.cs
- BinaryObjectReader.cs
- ManagementObjectSearcher.cs
- EntityProviderServices.cs
- PenCursorManager.cs
- PhoneCall.cs
- ToolBarTray.cs
- DragCompletedEventArgs.cs
- SerializableAttribute.cs
- TreeNodeClickEventArgs.cs
- AvTraceFormat.cs
- AuthenticationService.cs
- AuthorizationSection.cs
- DictationGrammar.cs
- InputEventArgs.cs
- ContainerActivationHelper.cs
- RegexMatchCollection.cs
- AttributeCollection.cs
- CurrencyWrapper.cs
- SafeLibraryHandle.cs
- HtmlTable.cs
- DynamicQueryableWrapper.cs
- ValueTypeFixupInfo.cs
- NegatedCellConstant.cs
- ChtmlLinkAdapter.cs
- CharacterHit.cs
- Rect3D.cs
- IconHelper.cs
- ThemeableAttribute.cs
- Parameter.cs
- Double.cs
- IsolatedStoragePermission.cs
- OleDbConnectionFactory.cs
- TriState.cs
- BaseHashHelper.cs
- FormsIdentity.cs
- OpenFileDialog.cs
- UnmanagedMemoryAccessor.cs
- TemplateKeyConverter.cs
- RijndaelCryptoServiceProvider.cs
- latinshape.cs
- Visual3D.cs
- ColumnResizeAdorner.cs
- TabPage.cs
- XmlCharCheckingReader.cs
- PlanCompilerUtil.cs
- DirtyTextRange.cs
- SoapDocumentServiceAttribute.cs
- PointLightBase.cs
- DbConnectionOptions.cs
- XmlObjectSerializer.cs
- SqlExpander.cs
- SmtpAuthenticationManager.cs
- _UriTypeConverter.cs
- DataReceivedEventArgs.cs
- LinqDataSourceDeleteEventArgs.cs
- CmsInterop.cs
- ReachNamespaceInfo.cs
- UpdatableGenericsFeature.cs
- EdmFunction.cs
- HwndProxyElementProvider.cs
- BackgroundWorker.cs
- DESCryptoServiceProvider.cs
- EventRecord.cs
- OracleParameter.cs
- ListMarkerSourceInfo.cs
- TransformPattern.cs
- FrameworkRichTextComposition.cs
- WebPartExportVerb.cs
- DataView.cs
- DecoderNLS.cs
- ButtonChrome.cs
- XmlFormatWriterGenerator.cs
- StrokeNodeEnumerator.cs
- BinaryObjectInfo.cs
- XPathNodeHelper.cs
- DictionarySectionHandler.cs
- CheckableControlBaseAdapter.cs
- PageThemeBuildProvider.cs
- OleDbErrorCollection.cs
- SingleTagSectionHandler.cs
- FilteredReadOnlyMetadataCollection.cs
- ResourceCollectionInfo.cs
- VirtualDirectoryMapping.cs
- XamlInt32CollectionSerializer.cs
- OneOf.cs
- CompilerGlobalScopeAttribute.cs
- HtmlInputControl.cs
- MemberProjectedSlot.cs
- SecurityHelper.cs
- OwnerDrawPropertyBag.cs
- PathGeometry.cs
- X509CertificateTrustedIssuerElement.cs
- NativeMethods.cs
- RequestCacheValidator.cs