Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / wpf / src / Framework / System / Windows / Controls / ViewBox.cs / 1 / ViewBox.cs
//---------------------------------------------------------------------------- // // Copyright (C) Microsoft Corporation. All rights reserved. // // File: Viewbox.cs // // Description: Contains the Viewbox Decorator class. // Spec at http://avalon/layout/Specs/Viewbox.xml // // History: // 09/25/2003 : greglett - Added to PDC_DEMO branch. // 06/09/2004 : t-jaredg - Updated with according to new specs // //--------------------------------------------------------------------------- using MS.Internal; using MS.Utility; using MS.Internal.Controls; using System.Diagnostics; using System.Collections; using System.Windows.Threading; using System.Windows.Media; using System.Windows.Documents; using System; namespace System.Windows.Controls { #region StretchDirection enum type ////// StretchDirection - Enum which describes when scaling should be used on the content of a Viewbox. This /// enum restricts the scaling factors along various axes. /// ///public enum StretchDirection { /// /// Only scales the content upwards when the content is smaller than the Viewbox. /// If the content is larger, no scaling downwards is done. /// UpOnly, ////// Only scales the content downwards when the content is larger than the Viewbox. /// If the content is smaller, no scaling upwards is done. /// DownOnly, ////// Always stretches to fit the Viewbox according to the stretch mode. /// Both } #endregion ////// public class Viewbox : Decorator { //------------------------------------------------------------------- // // Constructors // //------------------------------------------------------------------- #region Constructors ////// Default DependencyObject constructor /// ////// Automatic determination of current Dispatcher. Use alternative constructor /// that accepts a Dispatcher for best performance. /// public Viewbox() : base() { } #endregion //-------------------------------------------------------------------- // // Public Fields // //------------------------------------------------------------------- #region Public Fields ////// This is the DependencyProperty for the Viewbox's Stretch property. /// /// Default: Stretch.Uniform /// public static readonly DependencyProperty StretchProperty = DependencyProperty.Register( "Stretch", // Property name typeof(Stretch), // Property type typeof(Viewbox), // Property owner new FrameworkPropertyMetadata(Stretch.Uniform, FrameworkPropertyMetadataOptions.AffectsMeasure), new ValidateValueCallback(ValidateStretchValue)); private static bool ValidateStretchValue(object value) { Stretch s = (Stretch)value; return ( s == Stretch.Uniform || s == Stretch.None || s == Stretch.Fill || s == Stretch.UniformToFill); } ////// /// This is the DependencyProperty for the Viewbox's StretchDirection property. /// Default: StretchDirection.Both /// public static readonly DependencyProperty StretchDirectionProperty = DependencyProperty.Register( "StretchDirection", // Property name typeof(StretchDirection), // Property type typeof(Viewbox), // Property owner new FrameworkPropertyMetadata(StretchDirection.Both, FrameworkPropertyMetadataOptions.AffectsMeasure), new ValidateValueCallback(ValidateStretchDirectionValue)); private static bool ValidateStretchDirectionValue(object value) { StretchDirection sd = (StretchDirection)value; return ( sd == StretchDirection.Both || sd == StretchDirection.DownOnly || sd == StretchDirection.UpOnly); } #endregion //-------------------------------------------------------------------- // // Public Methods // //-------------------------------------------------------------------- //------------------------------------------------------------------- // // Public Properties // //-------------------------------------------------------------------- #region Public Properties private ContainerVisual InternalVisual { get { if(_internalVisual == null) { _internalVisual = new ContainerVisual(); AddVisualChild(_internalVisual); } return _internalVisual; } } private UIElement InternalChild { get { VisualCollection vc = InternalVisual.Children; if (vc.Count != 0) return vc[0] as UIElement; else return null; } set { VisualCollection vc = InternalVisual.Children; if (vc.Count != 0) vc.Clear(); vc.Add(value); } } private Transform InternalTransform { get { return InternalVisual.Transform; } set { InternalVisual.Transform = value; } } ////// /// The single child of a public override UIElement Child { //everything is the same as on Decorator, the only difference is to insert intermediate Visual to //specify scaling transform get { return InternalChild; } set { UIElement old = InternalChild; if(old != value) { //need to remove old element from logical tree RemoveLogicalChild(old); if(value != null) { AddLogicalChild(value); } InternalChild = value; InvalidateMeasure(); } } } ////// /// Returns the Visual children count. /// protected override int VisualChildrenCount { get { return 1; /* Always have internal container visual */ } } ////// Returns the child at the specified index. /// protected override Visual GetVisualChild(int index) { if (index != 0) { throw new ArgumentOutOfRangeException("index", index, SR.Get(SRID.Visual_ArgumentOutOfRange)); } return InternalVisual; } ////// Returns enumerator to logical children. /// protected internal override IEnumerator LogicalChildren { get { if (InternalChild == null) { return EmptyEnumerator.Instance; } return new SingleChildEnumerator(InternalChild); } } ////// Gets/Sets the Stretch mode of the Viewbox, which determines how the content will be /// fit into the Viewbox's space. /// /// ////// public Stretch Stretch { get { return (Stretch)GetValue(StretchProperty); } set { SetValue(StretchProperty, value); } } /// /// Gets/Sets the stretch direction of the Viewbox, which determines the restrictions on /// scaling that are applied to the content inside the Viewbox. For instance, this property /// can be used to prevent the content from being smaller than its native size or larger than /// its native size. /// ///public StretchDirection StretchDirection { get { return (StretchDirection)GetValue(StretchDirectionProperty); } set { SetValue(StretchDirectionProperty, value); } } #endregion Public Properties //------------------------------------------------------------------- // // Protected Methods // //------------------------------------------------------------------- #region Protected Methods /// /// Updates DesiredSize of the Viewbox. Called by parent UIElement. This is the first pass of layout. /// ////// Viewbox measures it's child at an infinite constraint; it allows the child to be however large it so desires. /// The child's returned size will be used as it's natural size for scaling to Viewbox's size during Arrange. /// /// Constraint size is an "upper limit" that the return value should not exceed. ///The Decorator's desired size. protected override Size MeasureOverride(Size constraint) { UIElement child = InternalChild; Size parentSize = new Size(); if (child != null) { // Initialize child constraint to infinity. We need to get a "natural" size for the child in absence of constraint. // Note that an author *can* impose a constraint on a child by using Height/Width, &c... properties Size infinteConstraint = new Size(Double.PositiveInfinity, Double.PositiveInfinity); child.Measure(infinteConstraint); Size childSize = child.DesiredSize; Size scalefac = ComputeScaleFactor(constraint, childSize, this.Stretch, this.StretchDirection); parentSize.Width = scalefac.Width * childSize.Width; parentSize.Height = scalefac.Height * childSize.Height; } return parentSize; } ////// Viewbox always sets the child to its desired size. It then computes and applies a transformation /// from that size to the space available: Viewbox's own input size less child margin. /// /// Viewbox also calls arrange on its child. /// /// Size in which Border will draw the borders/background and children. protected override Size ArrangeOverride(Size arrangeSize) { UIElement child = InternalChild; if (child != null) { Size childSize = child.DesiredSize; // Compute scaling factors from arrange size and the measured child content size Size scalefac = ComputeScaleFactor(arrangeSize, childSize, this.Stretch, this.StretchDirection); InternalTransform = new ScaleTransform(scalefac.Width, scalefac.Height); // Arrange the child to the desired size child.Arrange(new Rect(new Point(), child.DesiredSize)); //return the size oocupied by scaled child arrangeSize.Width = scalefac.Width * childSize.Width; arrangeSize.Height = scalefac.Height * childSize.Height; } return arrangeSize; } ////// This is a helper function that computes scale factors depending on a target size and a content size /// /// Size into which the content is being fitted. /// Size of the content, measured natively (unconstrained). /// Value of the Stretch property on the element. /// Value of the StretchDirection property on the element. internal static Size ComputeScaleFactor(Size availableSize, Size contentSize, Stretch stretch, StretchDirection stretchDirection) { // Compute scaling factors to use for axes double scaleX = 1.0; double scaleY = 1.0; bool isConstrainedWidth = !Double.IsPositiveInfinity(availableSize.Width); bool isConstrainedHeight = !Double.IsPositiveInfinity(availableSize.Height); if ( (stretch == Stretch.Uniform || stretch == Stretch.UniformToFill || stretch == Stretch.Fill) && (isConstrainedWidth || isConstrainedHeight) ) { // Compute scaling factors for both axes scaleX = (DoubleUtil.IsZero(contentSize.Width)) ? 0.0 : availableSize.Width / contentSize.Width; scaleY = (DoubleUtil.IsZero(contentSize.Height)) ? 0.0 : availableSize.Height / contentSize.Height; if (!isConstrainedWidth) scaleX = scaleY; else if (!isConstrainedHeight) scaleY = scaleX; else { // If not preserving aspect ratio, then just apply transform to fit switch (stretch) { case Stretch.Uniform: //Find minimum scale that we use for both axes double minscale = scaleX < scaleY ? scaleX : scaleY; scaleX = scaleY = minscale; break; case Stretch.UniformToFill: //Find maximum scale that we use for both axes double maxscale = scaleX > scaleY ? scaleX : scaleY; scaleX = scaleY = maxscale; break; case Stretch.Fill: //We already computed the fill scale factors above, so just use them break; } } //Apply stretch direction by bounding scales. //In the uniform case, scaleX=scaleY, so this sort of clamping will maintain aspect ratio //In the uniform fill case, we have the same result too. //In the fill case, note that we change aspect ratio, but that is okay switch(stretchDirection) { case StretchDirection.UpOnly: if (scaleX < 1.0) scaleX = 1.0; if (scaleY < 1.0) scaleY = 1.0; break; case StretchDirection.DownOnly: if (scaleX > 1.0) scaleX = 1.0; if (scaleY > 1.0) scaleY = 1.0; break; case StretchDirection.Both: break; default: break; } } //Return this as a size now return new Size(scaleX, scaleY); } #endregion Protected Methods //------------------------------------------------------------------- // // Private Fields // //-------------------------------------------------------------------- #region Private Fields private ContainerVisual _internalVisual; #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. // // File: Viewbox.cs // // Description: Contains the Viewbox Decorator class. // Spec at http://avalon/layout/Specs/Viewbox.xml // // History: // 09/25/2003 : greglett - Added to PDC_DEMO branch. // 06/09/2004 : t-jaredg - Updated with according to new specs // //--------------------------------------------------------------------------- using MS.Internal; using MS.Utility; using MS.Internal.Controls; using System.Diagnostics; using System.Collections; using System.Windows.Threading; using System.Windows.Media; using System.Windows.Documents; using System; namespace System.Windows.Controls { #region StretchDirection enum type ////// StretchDirection - Enum which describes when scaling should be used on the content of a Viewbox. This /// enum restricts the scaling factors along various axes. /// ///public enum StretchDirection { /// /// Only scales the content upwards when the content is smaller than the Viewbox. /// If the content is larger, no scaling downwards is done. /// UpOnly, ////// Only scales the content downwards when the content is larger than the Viewbox. /// If the content is smaller, no scaling upwards is done. /// DownOnly, ////// Always stretches to fit the Viewbox according to the stretch mode. /// Both } #endregion ////// public class Viewbox : Decorator { //------------------------------------------------------------------- // // Constructors // //------------------------------------------------------------------- #region Constructors ////// Default DependencyObject constructor /// ////// Automatic determination of current Dispatcher. Use alternative constructor /// that accepts a Dispatcher for best performance. /// public Viewbox() : base() { } #endregion //-------------------------------------------------------------------- // // Public Fields // //------------------------------------------------------------------- #region Public Fields ////// This is the DependencyProperty for the Viewbox's Stretch property. /// /// Default: Stretch.Uniform /// public static readonly DependencyProperty StretchProperty = DependencyProperty.Register( "Stretch", // Property name typeof(Stretch), // Property type typeof(Viewbox), // Property owner new FrameworkPropertyMetadata(Stretch.Uniform, FrameworkPropertyMetadataOptions.AffectsMeasure), new ValidateValueCallback(ValidateStretchValue)); private static bool ValidateStretchValue(object value) { Stretch s = (Stretch)value; return ( s == Stretch.Uniform || s == Stretch.None || s == Stretch.Fill || s == Stretch.UniformToFill); } ////// /// This is the DependencyProperty for the Viewbox's StretchDirection property. /// Default: StretchDirection.Both /// public static readonly DependencyProperty StretchDirectionProperty = DependencyProperty.Register( "StretchDirection", // Property name typeof(StretchDirection), // Property type typeof(Viewbox), // Property owner new FrameworkPropertyMetadata(StretchDirection.Both, FrameworkPropertyMetadataOptions.AffectsMeasure), new ValidateValueCallback(ValidateStretchDirectionValue)); private static bool ValidateStretchDirectionValue(object value) { StretchDirection sd = (StretchDirection)value; return ( sd == StretchDirection.Both || sd == StretchDirection.DownOnly || sd == StretchDirection.UpOnly); } #endregion //-------------------------------------------------------------------- // // Public Methods // //-------------------------------------------------------------------- //------------------------------------------------------------------- // // Public Properties // //-------------------------------------------------------------------- #region Public Properties private ContainerVisual InternalVisual { get { if(_internalVisual == null) { _internalVisual = new ContainerVisual(); AddVisualChild(_internalVisual); } return _internalVisual; } } private UIElement InternalChild { get { VisualCollection vc = InternalVisual.Children; if (vc.Count != 0) return vc[0] as UIElement; else return null; } set { VisualCollection vc = InternalVisual.Children; if (vc.Count != 0) vc.Clear(); vc.Add(value); } } private Transform InternalTransform { get { return InternalVisual.Transform; } set { InternalVisual.Transform = value; } } ////// /// The single child of a public override UIElement Child { //everything is the same as on Decorator, the only difference is to insert intermediate Visual to //specify scaling transform get { return InternalChild; } set { UIElement old = InternalChild; if(old != value) { //need to remove old element from logical tree RemoveLogicalChild(old); if(value != null) { AddLogicalChild(value); } InternalChild = value; InvalidateMeasure(); } } } ////// /// Returns the Visual children count. /// protected override int VisualChildrenCount { get { return 1; /* Always have internal container visual */ } } ////// Returns the child at the specified index. /// protected override Visual GetVisualChild(int index) { if (index != 0) { throw new ArgumentOutOfRangeException("index", index, SR.Get(SRID.Visual_ArgumentOutOfRange)); } return InternalVisual; } ////// Returns enumerator to logical children. /// protected internal override IEnumerator LogicalChildren { get { if (InternalChild == null) { return EmptyEnumerator.Instance; } return new SingleChildEnumerator(InternalChild); } } ////// Gets/Sets the Stretch mode of the Viewbox, which determines how the content will be /// fit into the Viewbox's space. /// /// ////// public Stretch Stretch { get { return (Stretch)GetValue(StretchProperty); } set { SetValue(StretchProperty, value); } } /// /// Gets/Sets the stretch direction of the Viewbox, which determines the restrictions on /// scaling that are applied to the content inside the Viewbox. For instance, this property /// can be used to prevent the content from being smaller than its native size or larger than /// its native size. /// ///public StretchDirection StretchDirection { get { return (StretchDirection)GetValue(StretchDirectionProperty); } set { SetValue(StretchDirectionProperty, value); } } #endregion Public Properties //------------------------------------------------------------------- // // Protected Methods // //------------------------------------------------------------------- #region Protected Methods /// /// Updates DesiredSize of the Viewbox. Called by parent UIElement. This is the first pass of layout. /// ////// Viewbox measures it's child at an infinite constraint; it allows the child to be however large it so desires. /// The child's returned size will be used as it's natural size for scaling to Viewbox's size during Arrange. /// /// Constraint size is an "upper limit" that the return value should not exceed. ///The Decorator's desired size. protected override Size MeasureOverride(Size constraint) { UIElement child = InternalChild; Size parentSize = new Size(); if (child != null) { // Initialize child constraint to infinity. We need to get a "natural" size for the child in absence of constraint. // Note that an author *can* impose a constraint on a child by using Height/Width, &c... properties Size infinteConstraint = new Size(Double.PositiveInfinity, Double.PositiveInfinity); child.Measure(infinteConstraint); Size childSize = child.DesiredSize; Size scalefac = ComputeScaleFactor(constraint, childSize, this.Stretch, this.StretchDirection); parentSize.Width = scalefac.Width * childSize.Width; parentSize.Height = scalefac.Height * childSize.Height; } return parentSize; } ////// Viewbox always sets the child to its desired size. It then computes and applies a transformation /// from that size to the space available: Viewbox's own input size less child margin. /// /// Viewbox also calls arrange on its child. /// /// Size in which Border will draw the borders/background and children. protected override Size ArrangeOverride(Size arrangeSize) { UIElement child = InternalChild; if (child != null) { Size childSize = child.DesiredSize; // Compute scaling factors from arrange size and the measured child content size Size scalefac = ComputeScaleFactor(arrangeSize, childSize, this.Stretch, this.StretchDirection); InternalTransform = new ScaleTransform(scalefac.Width, scalefac.Height); // Arrange the child to the desired size child.Arrange(new Rect(new Point(), child.DesiredSize)); //return the size oocupied by scaled child arrangeSize.Width = scalefac.Width * childSize.Width; arrangeSize.Height = scalefac.Height * childSize.Height; } return arrangeSize; } ////// This is a helper function that computes scale factors depending on a target size and a content size /// /// Size into which the content is being fitted. /// Size of the content, measured natively (unconstrained). /// Value of the Stretch property on the element. /// Value of the StretchDirection property on the element. internal static Size ComputeScaleFactor(Size availableSize, Size contentSize, Stretch stretch, StretchDirection stretchDirection) { // Compute scaling factors to use for axes double scaleX = 1.0; double scaleY = 1.0; bool isConstrainedWidth = !Double.IsPositiveInfinity(availableSize.Width); bool isConstrainedHeight = !Double.IsPositiveInfinity(availableSize.Height); if ( (stretch == Stretch.Uniform || stretch == Stretch.UniformToFill || stretch == Stretch.Fill) && (isConstrainedWidth || isConstrainedHeight) ) { // Compute scaling factors for both axes scaleX = (DoubleUtil.IsZero(contentSize.Width)) ? 0.0 : availableSize.Width / contentSize.Width; scaleY = (DoubleUtil.IsZero(contentSize.Height)) ? 0.0 : availableSize.Height / contentSize.Height; if (!isConstrainedWidth) scaleX = scaleY; else if (!isConstrainedHeight) scaleY = scaleX; else { // If not preserving aspect ratio, then just apply transform to fit switch (stretch) { case Stretch.Uniform: //Find minimum scale that we use for both axes double minscale = scaleX < scaleY ? scaleX : scaleY; scaleX = scaleY = minscale; break; case Stretch.UniformToFill: //Find maximum scale that we use for both axes double maxscale = scaleX > scaleY ? scaleX : scaleY; scaleX = scaleY = maxscale; break; case Stretch.Fill: //We already computed the fill scale factors above, so just use them break; } } //Apply stretch direction by bounding scales. //In the uniform case, scaleX=scaleY, so this sort of clamping will maintain aspect ratio //In the uniform fill case, we have the same result too. //In the fill case, note that we change aspect ratio, but that is okay switch(stretchDirection) { case StretchDirection.UpOnly: if (scaleX < 1.0) scaleX = 1.0; if (scaleY < 1.0) scaleY = 1.0; break; case StretchDirection.DownOnly: if (scaleX > 1.0) scaleX = 1.0; if (scaleY > 1.0) scaleY = 1.0; break; case StretchDirection.Both: break; default: break; } } //Return this as a size now return new Size(scaleX, scaleY); } #endregion Protected Methods //------------------------------------------------------------------- // // Private Fields // //-------------------------------------------------------------------- #region Private Fields private ContainerVisual _internalVisual; #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
- ClientSection.cs
- TrackingWorkflowEventArgs.cs
- ListItemConverter.cs
- TableChangeProcessor.cs
- PlanCompilerUtil.cs
- SmtpReplyReaderFactory.cs
- SingleTagSectionHandler.cs
- SQLBinaryStorage.cs
- InputLanguageSource.cs
- ProcessHostConfigUtils.cs
- SecurityListenerSettingsLifetimeManager.cs
- MimeTypeMapper.cs
- BasicKeyConstraint.cs
- ConsoleTraceListener.cs
- PagerSettings.cs
- ControlPropertyNameConverter.cs
- OdbcConnection.cs
- DllNotFoundException.cs
- DataRow.cs
- DispatcherSynchronizationContext.cs
- HttpChannelHelpers.cs
- BigInt.cs
- CodeMemberEvent.cs
- PrinterUnitConvert.cs
- MetadataPropertyCollection.cs
- SqlRecordBuffer.cs
- DataObjectCopyingEventArgs.cs
- SqlBulkCopyColumnMapping.cs
- ComponentFactoryHelpers.cs
- PartialCachingControl.cs
- UserPreferenceChangingEventArgs.cs
- ListViewGroupItemCollection.cs
- PropertyNames.cs
- FunctionNode.cs
- PasswordDeriveBytes.cs
- WebControlAdapter.cs
- ToolStripSettings.cs
- TextBounds.cs
- SafeCertificateContext.cs
- BuildDependencySet.cs
- WindowsPrincipal.cs
- SystemIPv4InterfaceProperties.cs
- FirewallWrapper.cs
- ContentFileHelper.cs
- CheckoutException.cs
- CompositeFontFamily.cs
- FillBehavior.cs
- Int32.cs
- AssemblyName.cs
- HttpModulesSection.cs
- DataGridViewCellConverter.cs
- UITypeEditor.cs
- ConnectionStringSettingsCollection.cs
- CryptoStream.cs
- RtfControlWordInfo.cs
- LicenseException.cs
- HtmlShimManager.cs
- InnerItemCollectionView.cs
- MailFileEditor.cs
- TreeView.cs
- Certificate.cs
- CaseStatement.cs
- LinkClickEvent.cs
- HMACRIPEMD160.cs
- HtmlLabelAdapter.cs
- SerialReceived.cs
- DateTimeStorage.cs
- SoapAttributeOverrides.cs
- DataGridSortingEventArgs.cs
- DataSourceConverter.cs
- TaskExtensions.cs
- processwaithandle.cs
- MyContact.cs
- UnmanagedMemoryStreamWrapper.cs
- DependsOnAttribute.cs
- GiveFeedbackEventArgs.cs
- CompositeTypefaceMetrics.cs
- ScrollBarRenderer.cs
- KnownTypes.cs
- WebReferencesBuildProvider.cs
- _AutoWebProxyScriptWrapper.cs
- QueryStringParameter.cs
- EncryptedData.cs
- XmlDocumentSchema.cs
- FlowDocumentFormatter.cs
- WebScriptMetadataInstanceContextProvider.cs
- ReadOnlyTernaryTree.cs
- PolyBezierSegment.cs
- EnumerableRowCollectionExtensions.cs
- ObjectDisposedException.cs
- ConstrainedDataObject.cs
- FileInfo.cs
- URLString.cs
- TextBox.cs
- LinkTarget.cs
- IsolatedStoragePermission.cs
- ConditionalAttribute.cs
- TextSpan.cs
- AmbiguousMatchException.cs
- XmlSchemaSubstitutionGroup.cs