Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Framework / System / Windows / Controls / Primitives / ToolBarOverflowPanel.cs / 1305600 / ToolBarOverflowPanel.cs
//----------------------------------------------------------------------------
//
// Copyright (C) Microsoft Corporation. All rights reserved.
//
//---------------------------------------------------------------------------
using System.Collections.Generic;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Windows.Documents;
using System;
using System.Diagnostics;
using MS.Internal;
namespace System.Windows.Controls.Primitives
{
///
/// ToolBarOverflowPanel
///
public class ToolBarOverflowPanel : Panel
{
#region Properties
///
/// WrapWidth Property
///
public static readonly DependencyProperty WrapWidthProperty =
DependencyProperty.Register(
"WrapWidth",
typeof(double),
typeof(ToolBarOverflowPanel),
new FrameworkPropertyMetadata(Double.NaN, FrameworkPropertyMetadataOptions.AffectsMeasure),
new ValidateValueCallback(IsWrapWidthValid));
///
/// WrapWidth Property
///
public double WrapWidth
{
get { return (double)GetValue(WrapWidthProperty); }
set { SetValue(WrapWidthProperty, value); }
}
private static bool IsWrapWidthValid(object value)
{
double v = (double)value;
return (DoubleUtil.IsNaN(v)) || (DoubleUtil.GreaterThanOrClose(v, 0d) && !Double.IsPositiveInfinity(v));
}
#endregion Properties
#region Override methods
///
/// Measure the content and store the desired size of the content
///
///
///
protected override Size MeasureOverride(Size constraint)
{
Size curLineSize = new Size();
_panelSize = new Size();
_wrapWidth = double.IsNaN(WrapWidth) ? constraint.Width : WrapWidth;
UIElementCollection children = InternalChildren;
int childrenCount = children.Count;
// Add ToolBar items which have IsOverflowItem = true
ToolBarPanel toolBarPanel = ToolBarPanel;
if (toolBarPanel != null)
{
// Go through the generated items collection and add to the children collection
// any that are marked IsOverFlowItem but aren't already in the children collection.
//
// The order of both collections matters.
//
// It is assumed that any children that were removed from generated items will have
// already been removed from the children collection.
List generatedItemsCollection = toolBarPanel.GeneratedItemsCollection;
int generatedItemsCount = (generatedItemsCollection != null) ? generatedItemsCollection.Count : 0;
int childrenIndex = 0;
for (int i = 0; i < generatedItemsCount; i++)
{
UIElement child = generatedItemsCollection[i];
if ((child != null) && ToolBar.GetIsOverflowItem(child) && !(child is Separator))
{
if (childrenIndex < childrenCount)
{
if (children[childrenIndex] != child)
{
children.Insert(childrenIndex, child);
childrenCount++;
}
}
else
{
children.Add(child);
childrenCount++;
}
childrenIndex++;
}
}
Debug.Assert(childrenIndex == childrenCount, "ToolBarOverflowPanel.Children count mismatch after transferring children from GeneratedItemsCollection.");
}
// Measure all children to determine if we need to increase desired wrapWidth
for (int i = 0; i < childrenCount; i++)
{
UIElement child = children[i] as UIElement;
child.Measure(constraint);
Size childDesiredSize = child.DesiredSize;
if (DoubleUtil.GreaterThan(childDesiredSize.Width, _wrapWidth))
{
_wrapWidth = childDesiredSize.Width;
}
}
// wrapWidth should not be bigger than constraint.Width
_wrapWidth = Math.Min(_wrapWidth, constraint.Width);
for (int i = 0; i < children.Count; i++)
{
UIElement child = children[i] as UIElement;
Size sz = child.DesiredSize;
if (DoubleUtil.GreaterThan(curLineSize.Width + sz.Width, _wrapWidth)) //need to switch to another line
{
_panelSize.Width = Math.Max(curLineSize.Width, _panelSize.Width);
_panelSize.Height += curLineSize.Height;
curLineSize = sz;
if (DoubleUtil.GreaterThan(sz.Width, _wrapWidth)) //the element is wider then the constraint - give it a separate line
{
_panelSize.Width = Math.Max(sz.Width, _panelSize.Width);
_panelSize.Height += sz.Height;
curLineSize = new Size();
}
}
else //continue to accumulate a line
{
curLineSize.Width += sz.Width;
curLineSize.Height = Math.Max(sz.Height, curLineSize.Height);
}
}
//the last line size, if any should be added
_panelSize.Width = Math.Max(curLineSize.Width, _panelSize.Width);
_panelSize.Height += curLineSize.Height;
return _panelSize;
}
///
/// Content arrangement.
///
///
///
protected override Size ArrangeOverride(Size arrangeBounds)
{
int firstInLine = 0;
Size curLineSize = new Size();
double accumulatedHeight = 0d;
_wrapWidth = Math.Min(_wrapWidth, arrangeBounds.Width);
UIElementCollection children = this.Children;
for (int i = 0; i < children.Count; i++)
{
Size sz = children[i].DesiredSize;
if (DoubleUtil.GreaterThan(curLineSize.Width + sz.Width, _wrapWidth)) //need to switch to another line
{
// Arrange the items in the current line not including the current
arrangeLine(accumulatedHeight, curLineSize.Height, firstInLine, i);
accumulatedHeight += curLineSize.Height;
// Current item will be first on the next line
firstInLine = i;
curLineSize = sz;
}
else //continue to accumulate a line
{
curLineSize.Width += sz.Width;
curLineSize.Height = Math.Max(sz.Height, curLineSize.Height);
}
}
arrangeLine(accumulatedHeight, curLineSize.Height, firstInLine, children.Count);
return _panelSize;
}
///
/// Creates a new UIElementCollection. Panel-derived class can create its own version of
/// UIElementCollection -derived class to add cached information to every child or to
/// intercept any Add/Remove actions (for example, for incremental layout update)
///
protected override UIElementCollection CreateUIElementCollection(FrameworkElement logicalParent)
{
// we ignore the Logical Parent (this) if we have ToolBar as our TemplatedParent
return new UIElementCollection(this, TemplatedParent == null ? logicalParent : null);
}
private void arrangeLine(double y, double lineHeight, int start, int end)
{
double x = 0;
UIElementCollection children = this.Children;
for (int i = start; i < end; i++)
{
UIElement child = children[i];
child.Arrange(new Rect(x, y, child.DesiredSize.Width, lineHeight));
x += child.DesiredSize.Width;
}
}
#endregion Override methods
#region private implementation
private ToolBar ToolBar
{
get { return TemplatedParent as ToolBar; }
}
private ToolBarPanel ToolBarPanel
{
get
{
ToolBar tb = ToolBar;
return tb == null ? null : tb.ToolBarPanel;
}
}
#endregion private implementation
#region private data
private double _wrapWidth; // calculated in MeasureOverride and used in ArrangeOverride
private Size _panelSize;
#endregion private data
}
}
// 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 System.Collections.Generic;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Windows.Documents;
using System;
using System.Diagnostics;
using MS.Internal;
namespace System.Windows.Controls.Primitives
{
///
/// ToolBarOverflowPanel
///
public class ToolBarOverflowPanel : Panel
{
#region Properties
///
/// WrapWidth Property
///
public static readonly DependencyProperty WrapWidthProperty =
DependencyProperty.Register(
"WrapWidth",
typeof(double),
typeof(ToolBarOverflowPanel),
new FrameworkPropertyMetadata(Double.NaN, FrameworkPropertyMetadataOptions.AffectsMeasure),
new ValidateValueCallback(IsWrapWidthValid));
///
/// WrapWidth Property
///
public double WrapWidth
{
get { return (double)GetValue(WrapWidthProperty); }
set { SetValue(WrapWidthProperty, value); }
}
private static bool IsWrapWidthValid(object value)
{
double v = (double)value;
return (DoubleUtil.IsNaN(v)) || (DoubleUtil.GreaterThanOrClose(v, 0d) && !Double.IsPositiveInfinity(v));
}
#endregion Properties
#region Override methods
///
/// Measure the content and store the desired size of the content
///
///
///
protected override Size MeasureOverride(Size constraint)
{
Size curLineSize = new Size();
_panelSize = new Size();
_wrapWidth = double.IsNaN(WrapWidth) ? constraint.Width : WrapWidth;
UIElementCollection children = InternalChildren;
int childrenCount = children.Count;
// Add ToolBar items which have IsOverflowItem = true
ToolBarPanel toolBarPanel = ToolBarPanel;
if (toolBarPanel != null)
{
// Go through the generated items collection and add to the children collection
// any that are marked IsOverFlowItem but aren't already in the children collection.
//
// The order of both collections matters.
//
// It is assumed that any children that were removed from generated items will have
// already been removed from the children collection.
List generatedItemsCollection = toolBarPanel.GeneratedItemsCollection;
int generatedItemsCount = (generatedItemsCollection != null) ? generatedItemsCollection.Count : 0;
int childrenIndex = 0;
for (int i = 0; i < generatedItemsCount; i++)
{
UIElement child = generatedItemsCollection[i];
if ((child != null) && ToolBar.GetIsOverflowItem(child) && !(child is Separator))
{
if (childrenIndex < childrenCount)
{
if (children[childrenIndex] != child)
{
children.Insert(childrenIndex, child);
childrenCount++;
}
}
else
{
children.Add(child);
childrenCount++;
}
childrenIndex++;
}
}
Debug.Assert(childrenIndex == childrenCount, "ToolBarOverflowPanel.Children count mismatch after transferring children from GeneratedItemsCollection.");
}
// Measure all children to determine if we need to increase desired wrapWidth
for (int i = 0; i < childrenCount; i++)
{
UIElement child = children[i] as UIElement;
child.Measure(constraint);
Size childDesiredSize = child.DesiredSize;
if (DoubleUtil.GreaterThan(childDesiredSize.Width, _wrapWidth))
{
_wrapWidth = childDesiredSize.Width;
}
}
// wrapWidth should not be bigger than constraint.Width
_wrapWidth = Math.Min(_wrapWidth, constraint.Width);
for (int i = 0; i < children.Count; i++)
{
UIElement child = children[i] as UIElement;
Size sz = child.DesiredSize;
if (DoubleUtil.GreaterThan(curLineSize.Width + sz.Width, _wrapWidth)) //need to switch to another line
{
_panelSize.Width = Math.Max(curLineSize.Width, _panelSize.Width);
_panelSize.Height += curLineSize.Height;
curLineSize = sz;
if (DoubleUtil.GreaterThan(sz.Width, _wrapWidth)) //the element is wider then the constraint - give it a separate line
{
_panelSize.Width = Math.Max(sz.Width, _panelSize.Width);
_panelSize.Height += sz.Height;
curLineSize = new Size();
}
}
else //continue to accumulate a line
{
curLineSize.Width += sz.Width;
curLineSize.Height = Math.Max(sz.Height, curLineSize.Height);
}
}
//the last line size, if any should be added
_panelSize.Width = Math.Max(curLineSize.Width, _panelSize.Width);
_panelSize.Height += curLineSize.Height;
return _panelSize;
}
///
/// Content arrangement.
///
///
///
protected override Size ArrangeOverride(Size arrangeBounds)
{
int firstInLine = 0;
Size curLineSize = new Size();
double accumulatedHeight = 0d;
_wrapWidth = Math.Min(_wrapWidth, arrangeBounds.Width);
UIElementCollection children = this.Children;
for (int i = 0; i < children.Count; i++)
{
Size sz = children[i].DesiredSize;
if (DoubleUtil.GreaterThan(curLineSize.Width + sz.Width, _wrapWidth)) //need to switch to another line
{
// Arrange the items in the current line not including the current
arrangeLine(accumulatedHeight, curLineSize.Height, firstInLine, i);
accumulatedHeight += curLineSize.Height;
// Current item will be first on the next line
firstInLine = i;
curLineSize = sz;
}
else //continue to accumulate a line
{
curLineSize.Width += sz.Width;
curLineSize.Height = Math.Max(sz.Height, curLineSize.Height);
}
}
arrangeLine(accumulatedHeight, curLineSize.Height, firstInLine, children.Count);
return _panelSize;
}
///
/// Creates a new UIElementCollection. Panel-derived class can create its own version of
/// UIElementCollection -derived class to add cached information to every child or to
/// intercept any Add/Remove actions (for example, for incremental layout update)
///
protected override UIElementCollection CreateUIElementCollection(FrameworkElement logicalParent)
{
// we ignore the Logical Parent (this) if we have ToolBar as our TemplatedParent
return new UIElementCollection(this, TemplatedParent == null ? logicalParent : null);
}
private void arrangeLine(double y, double lineHeight, int start, int end)
{
double x = 0;
UIElementCollection children = this.Children;
for (int i = start; i < end; i++)
{
UIElement child = children[i];
child.Arrange(new Rect(x, y, child.DesiredSize.Width, lineHeight));
x += child.DesiredSize.Width;
}
}
#endregion Override methods
#region private implementation
private ToolBar ToolBar
{
get { return TemplatedParent as ToolBar; }
}
private ToolBarPanel ToolBarPanel
{
get
{
ToolBar tb = ToolBar;
return tb == null ? null : tb.ToolBarPanel;
}
}
#endregion private implementation
#region private data
private double _wrapWidth; // calculated in MeasureOverride and used in ArrangeOverride
private Size _panelSize;
#endregion private data
}
}
// 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
- IDispatchConstantAttribute.cs
- DoWorkEventArgs.cs
- RtType.cs
- XmlBinaryReader.cs
- XAMLParseException.cs
- StrongNameIdentityPermission.cs
- ProfileServiceManager.cs
- DecimalConstantAttribute.cs
- ApplicationFileCodeDomTreeGenerator.cs
- ZoneMembershipCondition.cs
- HtmlElementEventArgs.cs
- CacheMode.cs
- SqlConnectionFactory.cs
- PathSegment.cs
- MessageBox.cs
- LocatorBase.cs
- MailWebEventProvider.cs
- ThicknessConverter.cs
- LeafCellTreeNode.cs
- FormViewCommandEventArgs.cs
- InstanceContext.cs
- DefaultEventAttribute.cs
- DataSourceUtil.cs
- FixedSOMLineCollection.cs
- Helper.cs
- NavigationWindow.cs
- HttpWebRequestElement.cs
- ItemCheckEvent.cs
- InstalledVoice.cs
- ProviderConnectionPoint.cs
- Fonts.cs
- DbProviderServices.cs
- OracleColumn.cs
- TransformerInfoCollection.cs
- NativeCompoundFileAPIs.cs
- ModuleConfigurationInfo.cs
- EventHandlingScope.cs
- querybuilder.cs
- TypeInitializationException.cs
- MenuCommand.cs
- GridViewColumn.cs
- xml.cs
- HostingPreferredMapPath.cs
- SaveFileDialog.cs
- EncryptedKeyHashIdentifierClause.cs
- Keywords.cs
- IisTraceListener.cs
- ErrorHandler.cs
- BookmarkUndoUnit.cs
- ToolTip.cs
- PersianCalendar.cs
- DbgCompiler.cs
- XmlnsDefinitionAttribute.cs
- DataGridViewCellMouseEventArgs.cs
- HostProtectionException.cs
- ISFClipboardData.cs
- SmiEventSink_DeferedProcessing.cs
- ByteAnimationBase.cs
- XmlILIndex.cs
- Drawing.cs
- QuaternionAnimationBase.cs
- MenuItemStyleCollection.cs
- UnionExpr.cs
- DoubleAnimationUsingPath.cs
- EditingScope.cs
- HwndSubclass.cs
- CodeTypeDelegate.cs
- SortedDictionary.cs
- HandlerBase.cs
- AvtEvent.cs
- DynamicFilterExpression.cs
- Vector3DConverter.cs
- HelpProvider.cs
- WSDualHttpBindingCollectionElement.cs
- HttpBufferlessInputStream.cs
- WindowsEditBox.cs
- DataFormats.cs
- FontUnit.cs
- MarkupProperty.cs
- SatelliteContractVersionAttribute.cs
- SQLDecimalStorage.cs
- TextTreeInsertUndoUnit.cs
- shaperfactoryquerycacheentry.cs
- DesignerDataView.cs
- ServiceOperationParameter.cs
- Restrictions.cs
- QilCloneVisitor.cs
- InProcStateClientManager.cs
- PortCache.cs
- GridViewRowCollection.cs
- NativeWindow.cs
- FieldMetadata.cs
- WebPartConnectionsConnectVerb.cs
- InternalUserCancelledException.cs
- ToolStripMenuItem.cs
- CommandEventArgs.cs
- Msmq.cs
- FixedDocument.cs
- IconConverter.cs
- Rule.cs