Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / WinForms / Managed / System / WinForms / Layout / CommonProperties.cs / 1305376 / CommonProperties.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- namespace System.Windows.Forms.Layout { using System; using System.Collections.Specialized; using System.Collections; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Drawing; using System.Windows.Forms; using System.ComponentModel; // Some LayoutEngines extend the same properties to their children. We want // these extended properties to retain their value when moved from one container // to another. (For example, set BoxStretchInternal on a control in FlowPanel and then move // the control to GridPanel.) CommonProperties is a place to define keys and // accessors for such properties. internal class CommonProperties { private static readonly int _layoutStateProperty = PropertyStore.CreateKey(); private static readonly int _specifiedBoundsProperty = PropertyStore.CreateKey(); private static readonly int _preferredSizeCacheProperty = PropertyStore.CreateKey(); private static readonly int _paddingProperty = PropertyStore.CreateKey(); private static readonly int _marginProperty = PropertyStore.CreateKey(); private static readonly int _minimumSizeProperty = PropertyStore.CreateKey(); private static readonly int _maximumSizeProperty = PropertyStore.CreateKey(); private static readonly int _layoutBoundsProperty = PropertyStore.CreateKey(); #if DEBUG private static readonly int _lastKnownStateProperty = PropertyStore.CreateKey(); #endif internal const ContentAlignment DefaultAlignment = ContentAlignment.TopLeft; internal const AnchorStyles DefaultAnchor = AnchorStyles.Top | AnchorStyles.Left; internal const bool DefaultAutoSize = false; internal const DockStyle DefaultDock = DockStyle.None; internal static readonly Padding DefaultMargin = new Padding(3); internal static readonly Size DefaultMinimumSize = new Size(0, 0); internal static readonly Size DefaultMaximumSize = new Size(0, 0); // DO NOT MOVE THE FOLLOWING 4 SECTIONS // We have done some special arranging here so that if the first 7 bits of state are zero, we know // that the control is purely absolutely positioned and DefaultLayout does not need to do // anything. // private static readonly BitVector32.Section _dockAndAnchorNeedsLayoutSection = BitVector32.CreateSection(0x7F); private static readonly BitVector32.Section _dockAndAnchorSection = BitVector32.CreateSection(0x0F); private static readonly BitVector32.Section _dockModeSection = BitVector32.CreateSection(0x01, _dockAndAnchorSection); private static readonly BitVector32.Section _autoSizeSection = BitVector32.CreateSection(0x01, _dockModeSection); private static readonly BitVector32.Section _BoxStretchInternalSection = BitVector32.CreateSection(0x03, _autoSizeSection); private static readonly BitVector32.Section _anchorNeverShrinksSection = BitVector32.CreateSection(0x01, _BoxStretchInternalSection); private static readonly BitVector32.Section _flowBreakSection = BitVector32.CreateSection(0x01, _anchorNeverShrinksSection); private static readonly BitVector32.Section _selfAutoSizingSection = BitVector32.CreateSection(0x01, _flowBreakSection); private static readonly BitVector32.Section _autoSizeModeSection = BitVector32.CreateSection(0x01, _selfAutoSizingSection); private enum DockAnchorMode{ Anchor = 0, Dock = 1 } #region AppliesToAllLayouts /// ClearMaximumSize /// Removes the maximum size from the property store, making it "unset". /// internal static void ClearMaximumSize(IArrangedElement element) { if (element.Properties.ContainsObject(_maximumSizeProperty)) { element.Properties.RemoveObject(_maximumSizeProperty); } } /// GetAutoSize /// Determines whether or not the System.Windows.Forms.Layout LayoutEngines /// think the element is AutoSized. /// /// A control can thwart the layout engine by overriding its virtual AutoSize /// property and not calling base. If CommonProperties.GetAutoSize(element) is false, /// a layout engine will treat it as AutoSize = false and not size the element to its /// preferred size. [System.Runtime.TargetedPatchingOptOutAttribute("Performance critical to inline across NGen image boundaries")] internal static bool GetAutoSize(IArrangedElement element) { BitVector32 state = GetLayoutState(element); int value = state[_autoSizeSection]; return value != 0; } /// GetMargin /// Returns the Margin (exterior space) for an item /// /// We can not use our pattern of passing the default value into Margin because the /// LayoutEngines read this property and do not know each element's DefaultMargin. /// Instead the Element sets the Margin in its ctor. [System.Runtime.TargetedPatchingOptOutAttribute("Performance critical to inline across NGen image boundaries")] internal static Padding GetMargin(IArrangedElement element) { bool found; Padding padding = element.Properties.GetPadding(_marginProperty, out found); if (found) { return padding; } return DefaultMargin; } /// GetMaximumSize /// Returns the maximum size for an element internal static Size GetMaximumSize(IArrangedElement element, Size defaultMaximumSize) { bool found; Size size = element.Properties.GetSize(_maximumSizeProperty, out found); if (found) { return size; } return defaultMaximumSize; } /// GetMinimumSize /// Returns the minimum size for an element internal static Size GetMinimumSize(IArrangedElement element, Size defaultMinimumSize) { bool found; Size size = element.Properties.GetSize(_minimumSizeProperty, out found); if (found) { return size; } return defaultMinimumSize; } /// GetPadding /// Returns the padding for an element /// Typically the padding is accounted for in either the DisplayRectangle calculation /// and/or the GetPreferredSize calculation of a control. /// /// NOTE: LayoutEngines should never read this property. Padding gets incorperated into /// layout by modifying what the control reports for preferred size. [System.Runtime.TargetedPatchingOptOutAttribute("Performance critical to inline across NGen image boundaries")] internal static Padding GetPadding(IArrangedElement element, Padding defaultPadding) { bool found; Padding padding = element.Properties.GetPadding(_paddingProperty, out found); if (found) { return padding; } return defaultPadding; } /// GetSpecifiedBounds /// Returns the last size manually set into the element. See UpdateSpecifiedBounds. internal static Rectangle GetSpecifiedBounds(IArrangedElement element) { bool found; Rectangle rectangle = element.Properties.GetRectangle(_specifiedBoundsProperty, out found); if (found && rectangle != LayoutUtils.MaxRectangle) { return rectangle; } return element.Bounds; } /// ResetPadding /// clears out the padding from the property store internal static void ResetPadding(IArrangedElement element) { object value = element.Properties.GetObject(_paddingProperty); if(value != null) { element.Properties.RemoveObject(_paddingProperty); } } /// SetAutoSize /// Sets whether or not the layout engines should treat this control as auto sized. internal static void SetAutoSize(IArrangedElement element, bool value) { Debug.Assert(value != GetAutoSize(element), "PERF: Caller should guard against setting AutoSize to original value."); BitVector32 state = GetLayoutState(element); state[_autoSizeSection] = value ? 1 : 0; SetLayoutState(element, state); if(value == false) { // If autoSize is being turned off, restore the control to its specified bounds. element.SetBounds(GetSpecifiedBounds(element), BoundsSpecified.None); } Debug.Assert(GetAutoSize(element) == value, "Error detected setting AutoSize."); } /// SetMargin /// Sets the margin (exterior space) for an element. internal static void SetMargin(IArrangedElement element, Padding value) { Debug.Assert(value != GetMargin(element), "PERF: Caller should guard against setting Margin to original value."); element.Properties.SetPadding(_marginProperty, value); Debug.Assert(GetMargin(element) == value, "Error detected setting Margin."); LayoutTransaction.DoLayout(element.Container, element, PropertyNames.Margin); } /// SetMaximumSize /// Sets the maximum size for an element. internal static void SetMaximumSize(IArrangedElement element, Size value) { Debug.Assert(value != GetMaximumSize(element, new Size(-7109, -7107)), "PERF: Caller should guard against setting MaximumSize to original value."); element.Properties.SetSize(_maximumSizeProperty, value); // Element bounds may need to truncated to new maximum // Rectangle bounds = element.Bounds; bounds.Width = Math.Min(bounds.Width, value.Width); bounds.Height = Math.Min(bounds.Height, value.Height); element.SetBounds(bounds, BoundsSpecified.Size); // element.SetBounds does a SetBoundsCore. We still need to explicitly refresh parent layout. LayoutTransaction.DoLayout(element.Container, element, PropertyNames.MaximumSize); Debug.Assert(GetMaximumSize(element, new Size(-7109, -7107)) == value, "Error detected setting MaximumSize."); } /// SetMinimumSize /// Sets the minimum size for an element. internal static void SetMinimumSize(IArrangedElement element, Size value) { Debug.Assert(value != GetMinimumSize(element, new Size(-7109, -7107)), "PERF: Caller should guard against setting MinimumSize to original value."); element.Properties.SetSize(_minimumSizeProperty, value); using (new LayoutTransaction(element.Container as Control, element, PropertyNames.MinimumSize)) { // Element bounds may need to inflated to new minimum // Rectangle bounds = element.Bounds; bounds.Width = Math.Max(bounds.Width, value.Width); bounds.Height = Math.Max(bounds.Height, value.Height); element.SetBounds(bounds, BoundsSpecified.Size); } Debug.Assert(GetMinimumSize(element, new Size(-7109, -7107)) == value, "Error detected setting MinimumSize."); } /// SetPadding /// Sets the padding (interior space) for an element. See GetPadding for more detiails. /// NOTE: It is the callers responsibility to do layout. See Control.Padding for details. internal static void SetPadding(IArrangedElement element, Padding value) { Debug.Assert(value != GetPadding(element, new Padding(-7105)), "PERF: Caller should guard against setting Padding to original value."); value = LayoutUtils.ClampNegativePaddingToZero(value); element.Properties.SetPadding(_paddingProperty, value); Debug.Assert(GetPadding(element, new Padding(-7105)) == value, "Error detected setting Padding."); } /// UpdateSpecifiedBounds /// The main purpose of this function is to remember what size someone specified in the Size, Width, Height, Bounds /// property. (Its the whole reason the BoundsSpecified enum exists.) Consider this scenario. You set a Button /// to DockStyle.Fill, then DockStyle.None. When Dock.Filled, the Size changed to 300,300. When you /// set it back to DockStyle.None, the size switches back to 100,23. How does this happen? /// /// Setting the control to Dock.Fill (via DefaultLayout engine) /// element.SetBounds(newElementBounds, BoundsSpecified.None); /// /// (If someone happens to set the Size property here the specified bounds gets updated via Control.Size) /// SetBounds(x, y, value.Width, value.Height, BoundsSpecified.Size); /// /// Setting the control to Dock.None (via DefaultLayout.SetDock) /// element.SetBounds(CommonProperties.GetSpecifiedBounds(element), BoundsSpecified.None); internal static void UpdateSpecifiedBounds(IArrangedElement element, int x, int y, int width, int height, BoundsSpecified specified) { Rectangle originalBounds = CommonProperties.GetSpecifiedBounds(element); // PERF note: Bitwise operator usage intentional to optimize out branching. bool xChangedButNotSpecified = ((specified & BoundsSpecified.X) == BoundsSpecified.None) & x != originalBounds.X; bool yChangedButNotSpecified = ((specified & BoundsSpecified.Y) == BoundsSpecified.None) & y != originalBounds.Y; bool wChangedButNotSpecified = ((specified & BoundsSpecified.Width) == BoundsSpecified.None) & width != originalBounds.Width; bool hChangedButNotSpecified = ((specified & BoundsSpecified.Height) == BoundsSpecified.None) & height != originalBounds.Height; if(xChangedButNotSpecified | yChangedButNotSpecified | wChangedButNotSpecified | hChangedButNotSpecified) { // if any of them are changed and specified cache the new value. if (!xChangedButNotSpecified) originalBounds.X = x; if (!yChangedButNotSpecified) originalBounds.Y = y; if (!wChangedButNotSpecified) originalBounds.Width = width; if (!hChangedButNotSpecified) originalBounds.Height = height; element.Properties.SetRectangle(_specifiedBoundsProperty, originalBounds); } else { // SetBoundsCore is going to call this a lot with the same bounds. Avoid the set object // (which indirectly may causes an allocation) if we can. if(element.Properties.ContainsObject(_specifiedBoundsProperty)) { // use MaxRectangle instead of null so we can reuse the SizeWrapper in the property store. element.Properties.SetRectangle(_specifiedBoundsProperty, LayoutUtils.MaxRectangle); } } } // Used by ToolStripControlHost.Size. internal static void UpdateSpecifiedBounds(IArrangedElement element, int x, int y, int width, int height) { Rectangle bounds = new Rectangle(x, y, width, height); element.Properties.SetRectangle(_specifiedBoundsProperty, bounds); } /// xClearPreferredSizeCache /// clears the preferred size cached for any control that overrides /// the internal GetPreferredSizeCore method. DO NOT CALL DIRECTLY /// unless it is understood how the size of the control is going to be updated. /// [System.Runtime.TargetedPatchingOptOutAttribute("Performance critical to inline across NGen image boundaries")] internal static void xClearPreferredSizeCache(IArrangedElement element) { element.Properties.SetSize(_preferredSizeCacheProperty, LayoutUtils.InvalidSize); #if DEBUG Debug_ClearProperties(element); #endif Debug.Assert(xGetPreferredSizeCache(element) == Size.Empty, "Error detected in xClearPreferredSizeCache."); } /// xClearAllPreferredSizeCaches /// clears all the caching for an IArrangedElement hierarchy /// typically done in dispose. internal static void xClearAllPreferredSizeCaches(IArrangedElement start) { CommonProperties.xClearPreferredSizeCache(start); ArrangedElementCollection controlsCollection = start.Children; // This may have changed the sizes of our children. // PERFNOTE: This is more efficient than using Foreach. Foreach // forces the creation of an array subset enum each time we // enumerate for(int i = 0; i < controlsCollection.Count; i++) { xClearAllPreferredSizeCaches(controlsCollection[i]); } } /// xGetPreferredSizeCache /// This value is the cached result of the return value from /// a control's GetPreferredSizeCore implementation when asked /// for a constraining value of LayoutUtils.MaxValue (or Size.Empty too). internal static Size xGetPreferredSizeCache(IArrangedElement element) { bool found; Size size = element.Properties.GetSize(_preferredSizeCacheProperty, out found); if (found && (size != LayoutUtils.InvalidSize)) { return size; } return Size.Empty; } /// xSetPreferredSizeCache /// Sets a control's preferred size. See xGetPreferredSizeCache. internal static void xSetPreferredSizeCache(IArrangedElement element, Size value) { Debug.Assert(value == Size.Empty || value != xGetPreferredSizeCache(element), "PERF: Caller should guard against setting PreferredSizeCache to original value."); #if DEBUG Debug_SnapProperties(element); #endif element.Properties.SetSize(_preferredSizeCacheProperty, value); Debug.Assert(xGetPreferredSizeCache(element) == value, "Error detected in xGetPreferredSizeCache."); } #endregion #region DockAndAnchorLayoutSpecific /// GetAutoSizeMode /// Returns whether or not a control should snap to its smallest size /// or retain its original size and only grow if the preferred size is larger. /// We tried not having GrowOnly as the default, but it becomes difficult /// to design panels or have Buttons maintain their default size of 100,23 internal static AutoSizeMode GetAutoSizeMode(IArrangedElement element) { BitVector32 state = GetLayoutState(element); return state[_autoSizeModeSection] == 0 ? AutoSizeMode.GrowOnly : AutoSizeMode.GrowAndShrink; } /// GetNeedsDockAndAnchorLayout /// Do not use. Internal property for DockAndAnchor layout. /// Returns true if DefaultLayout needs to do any work for this element. /// (Returns false if the element is purely absolutely positioned) internal static bool GetNeedsDockAndAnchorLayout(IArrangedElement element) { BitVector32 state = GetLayoutState(element); bool result = state[_dockAndAnchorNeedsLayoutSection] != 0; Debug.Assert( (xGetAnchor(element) == DefaultAnchor && xGetDock(element) == DefaultDock && GetAutoSize(element) == DefaultAutoSize) != result, "Individual values of Anchor/Dock/AutoRelocate/Autosize contradict GetNeedsDockAndAnchorLayout()."); return result; } /// GetNeedsAnchorLayout /// Do not use. Internal property for DockAndAnchor layout. /// Returns true if DefaultLayout needs to do anchoring for this element. internal static bool GetNeedsAnchorLayout(IArrangedElement element) { BitVector32 state = GetLayoutState(element); bool result = (state[_dockAndAnchorNeedsLayoutSection] != 0) && (state[_dockModeSection] == (int) DockAnchorMode.Anchor); Debug.Assert( (xGetAnchor(element) != DefaultAnchor || (GetAutoSize(element) != DefaultAutoSize && xGetDock(element) == DockStyle.None)) == result, "Individual values of Anchor/Dock/AutoRelocate/Autosize contradict GetNeedsAnchorLayout()."); return result; } /// GetNeedsDockLayout /// Do not use. Internal property for DockAndAnchor layout. /// Returns true if DefaultLayout needs to do docking for this element. internal static bool GetNeedsDockLayout(IArrangedElement element) { BitVector32 state = GetLayoutState(element); bool result = state[_dockModeSection] == (int) DockAnchorMode.Dock && element.ParticipatesInLayout; Debug.Assert(((xGetDock(element) != DockStyle.None) && element.ParticipatesInLayout) == result, "Error detected in GetNeedsDockLayout()."); return result; } /// GetSelfAutoSize /// Compat flag for controls that previously sized themselves. /// Some controls rolled their own implementation of AutoSize in V1 for Dock & Anchor /// In V2, the LayoutEngine is the one responsible for sizing the child items when /// they're AutoSized. For new layout engines, the controls will let the layout engine /// size them, but for DefaultLayout, they're left to size themselves. internal static bool GetSelfAutoSizeInDefaultLayout(IArrangedElement element) { BitVector32 state = GetLayoutState(element); int value = state[_selfAutoSizingSection]; return (value == 1); } /// SetAutoSizeMode /// Returns whether or not a control should snap to its smallest size /// or retain its original size and only grow if the preferred size is larger. /// We tried not having GrowOnly as the default, but it becomes difficult /// to design panels or have Buttons maintain their default size of 100,23 internal static void SetAutoSizeMode(IArrangedElement element, AutoSizeMode mode) { BitVector32 state = GetLayoutState(element); state[_autoSizeModeSection] = mode == AutoSizeMode.GrowAndShrink ? 1 : 0; SetLayoutState(element, state); } /// ShouldSelfSize /// Compat flag for controls that previously sized themselves. /// See GetSelfAutoSize comments. internal static bool ShouldSelfSize(IArrangedElement element) { if (GetAutoSize(element)) { // check for legacy layout engine if (element.Container is Control) { if (((Control)element.Container).LayoutEngine is DefaultLayout) { return GetSelfAutoSizeInDefaultLayout(element); } } // else // - unknown element type // - new LayoutEngine which should set the size to the preferredSize anyways. return false; } // autosize false things should selfsize. return true; } /// SetSelfAutoSizeInDefaultLayout /// Compat flag for controls that previously sized themselves. /// See GetSelfAutoSize comments. internal static void SetSelfAutoSizeInDefaultLayout(IArrangedElement element, bool value) { Debug.Assert(value != GetSelfAutoSizeInDefaultLayout(element), "PERF: Caller should guard against setting AutoSize to original value."); BitVector32 state = GetLayoutState(element); state[_selfAutoSizingSection] = value ? 1 : 0; SetLayoutState(element, state); Debug.Assert(GetSelfAutoSizeInDefaultLayout(element) == value, "Error detected setting AutoSize."); } /// xGetAnchor - /// Do not use this. Use DefaultLayout.GetAnchor. /// NOTE that Dock and Anchor are exclusive, so we store their enums in the same section. internal static AnchorStyles xGetAnchor(IArrangedElement element) { BitVector32 state = GetLayoutState(element); AnchorStyles value = (AnchorStyles) state[_dockAndAnchorSection]; DockAnchorMode mode = (DockAnchorMode) state[_dockModeSection]; // If we are docked, or if it the value is 0, we return DefaultAnchor value = mode == DockAnchorMode.Anchor ? xTranslateAnchorValue(value) : DefaultAnchor; Debug.Assert(mode == DockAnchorMode.Anchor || value == DefaultAnchor, "xGetAnchor needs to return DefaultAnchor when docked."); return value; } /// xGetAutoSizedAndAnchored - /// Do not use. Internal property for DockAndAnchor layout. /// Returns true if the element is both AutoSized and Anchored. internal static bool xGetAutoSizedAndAnchored(IArrangedElement element) { BitVector32 state = GetLayoutState(element); if (state[_selfAutoSizingSection] != 0) { return false; } bool result = (state[_autoSizeSection] != 0) && (state[_dockModeSection] == (int) DockAnchorMode.Anchor); Debug.Assert(result == (GetAutoSize(element) && xGetDock(element) == DockStyle.None), "Error detected in xGetAutoSizeAndAnchored."); return result; } /// xGetDock /// Do not use this. Use DefaultLayout.GetDock. /// Note that Dock and Anchor are exclusive, so we store their enums in the same section. internal static DockStyle xGetDock(IArrangedElement element) { BitVector32 state = GetLayoutState(element); DockStyle value = (DockStyle) state[_dockAndAnchorSection]; DockAnchorMode mode = (DockAnchorMode) state[_dockModeSection]; // If we are anchored we return DefaultDock value = mode == DockAnchorMode.Dock ? value : DefaultDock; Debug.Assert(ClientUtils.IsEnumValid(value, (int)value, (int)DockStyle.None, (int)DockStyle.Fill), "Illegal value returned form xGetDock."); Debug.Assert(mode == DockAnchorMode.Dock || value == DefaultDock, "xGetDock needs to return the DefaultDock style when not docked."); return value; } /// xSetAnchor - /// Do not use this. Use DefaultLayout.SetAnchor. /// Note that Dock and Anchor are exclusive, so we store their enums in the same section. internal static void xSetAnchor(IArrangedElement element, AnchorStyles value) { Debug.Assert(value != xGetAnchor(element), "PERF: Caller should guard against setting Anchor to original value."); BitVector32 state = GetLayoutState(element); // We translate DefaultAnchor to zero - see the _dockAndAnchorNeedsLayoutSection section above. state[_dockAndAnchorSection] = (int) xTranslateAnchorValue(value); state[_dockModeSection] = (int) DockAnchorMode.Anchor; SetLayoutState(element, state); Debug.Assert(xGetAnchor(element) == value, "Error detected setting Anchor."); Debug.Assert(GetLayoutState(element)[_dockModeSection] == (int) DockAnchorMode.Anchor, "xSetAnchor did not set mode to Anchor."); } /// xSetDock /// Do not use this. Use DefaultLayout.SetDock. /// Note that Dock and Anchor are exclusive, so we store their enums in the same section. internal static void xSetDock(IArrangedElement element, DockStyle value) { Debug.Assert(value != xGetDock(element), "PERF: Caller should guard against setting Dock to original value."); Debug.Assert(ClientUtils.IsEnumValid(value, (int)value, (int)DockStyle.None, (int)DockStyle.Fill), "Illegal value passed to xSetDock."); BitVector32 state = GetLayoutState(element); state[_dockAndAnchorSection] = (int) value; // See xTranslateAnchorValue for why this works with Dock.None. state[_dockModeSection] = (int) (value == DockStyle.None ? DockAnchorMode.Anchor : DockAnchorMode.Dock); SetLayoutState(element, state); Debug.Assert(xGetDock(element) == value, "Error detected setting Dock."); Debug.Assert((GetLayoutState(element)[_dockModeSection] == (int) DockAnchorMode.Dock) == (value != DockStyle.None), "xSetDock set DockMode incorrectly."); } /// xTranslateAnchorValue - /// Helper method for xGetAnchor / xSetAnchor. /// We store anchor DefualtAnchor as None and vice versa. /// We either had to do this or map Dock.None to DefaultAnchor (Dock & Anchor share the same section /// in LayoutState.) Mapping DefaultAnchor to 0 is nicer because we do not need to allocate anything in /// the PropertyStore to get a 0 back from PropertyStore.GetInteger(). private static AnchorStyles xTranslateAnchorValue(AnchorStyles anchor) { switch(anchor) { case AnchorStyles.None: return DefaultAnchor; case DefaultAnchor: return AnchorStyles.None; } return anchor; } #endregion #region FlowLayoutSpecific // internal static bool GetFlowBreak(IArrangedElement element) { BitVector32 state = GetLayoutState(element); int value = state[_flowBreakSection]; return value == 1; } /// SetFlowBreak /// Use FlowLayoutSettings.SetFlowBreak instead. /// See GetFlowBreak. internal static void SetFlowBreak(IArrangedElement element, bool value) { Debug.Assert(value != GetFlowBreak(element), "PERF: Caller should guard against setting FlowBreak to original value."); BitVector32 state = GetLayoutState(element); state[_flowBreakSection] = value ? 1 : 0; SetLayoutState(element, state); LayoutTransaction.DoLayout(element.Container, element, PropertyNames.FlowBreak); Debug.Assert(GetFlowBreak(element) == value, "Error detected setitng SetFlowBreak."); } #endregion #region AutoScrollSpecific /// GetLayoutBounds - /// This is the size used to determine whether or not we need scrollbars. /// /// Used if the layoutengine always want to return the same layout bounds regardless /// of how it lays out. Example is TLP in RTL and LTR. VSWhidbey# 392913 internal static Size GetLayoutBounds(IArrangedElement element) { bool found; Size size = element.Properties.GetSize(_layoutBoundsProperty, out found); if (found) { return size; } return Size.Empty; } /// SetLayoutBounds - /// This is the size used to determine whether or not we need scrollbars. /// /// The TableLayout engine now calls CommonProperties.SetLayoutBounds when /// it is done with its layout. The layoutbounds are the total column width /// and the total row height. ScrollableControl checks if the LayoutBounds /// has been set in the CommonProperties when it tries to figure out if it /// should add scrollbars - but only if the layout engine is not the default /// layout engine. If the bounds has been set, ScrollableControl will use /// those bounds to check if scrollbars should be added, rather than doing /// its own magic to figure it out. internal static void SetLayoutBounds(IArrangedElement element, Size value) { element.Properties.SetSize(_layoutBoundsProperty, value); } /// HasLayoutBounds - /// Returns whether we have layout bounds stored for this element. internal static bool HasLayoutBounds(IArrangedElement element) { bool found; element.Properties.GetSize(_layoutBoundsProperty, out found); return found; } #endregion #region InternalCommonPropertiesHelpers /// GetLayoutState - returns the layout state bit vector from the property store. /// CAREFUL: this is a copy of the state. You need to SetLayoutState() to save your changes. /// [System.Runtime.TargetedPatchingOptOutAttribute("Performance critical to inline across NGen image boundaries")] internal static BitVector32 GetLayoutState(IArrangedElement element) { return new BitVector32(element.Properties.GetInteger(_layoutStateProperty)); } internal static void SetLayoutState(IArrangedElement element, BitVector32 state) { element.Properties.SetInteger(_layoutStateProperty, state.Data); } #endregion #region DebugHelpers #if DEBUG internal static readonly TraceSwitch PreferredSize = new TraceSwitch("PreferredSize", "Debug preferred size assertion"); internal static string Debug_GetChangedProperties(IArrangedElement element) { string diff = ""; if (PreferredSize.TraceVerbose) { Hashtable propertyHash = element.Properties.GetObject(_lastKnownStateProperty) as Hashtable; if(propertyHash != null) { foreach (PropertyDescriptor pd in TypeDescriptor.GetProperties(element)) { if (propertyHash.ContainsKey(pd.Name) && (propertyHash[pd.Name].ToString() != pd.Converter.ConvertToString(pd.GetValue(element)))) { diff += "Prop [ " + pd.Name + "] OLD [" + propertyHash[pd.Name] + "] NEW [" + pd.Converter.ConvertToString(pd.GetValue(element)) + "]\r\n"; } } } } else { diff = "For more info, try enabling PreferredSize trace switch"; } return diff; } internal static void Debug_SnapProperties(IArrangedElement element) { // DEBUG - store off the old state so we can figure out what has changed in a GPS assert element.Properties.SetObject(_lastKnownStateProperty, Debug_GetCurrentPropertyState(element)); } internal static void Debug_ClearProperties(IArrangedElement element) { // DEBUG - clear off the old state so we can figure out what has changed in a GPS assert element.Properties.SetObject(_lastKnownStateProperty, null); } [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] public static Hashtable Debug_GetCurrentPropertyState(object obj) { Hashtable propertyHash = new Hashtable(); if (PreferredSize.TraceVerbose) { foreach (PropertyDescriptor pd in TypeDescriptor.GetProperties(obj)) { if (pd.Name == "PreferredSize") { continue; // avoid accidentally forcing a call to GetPreferredSize } try { if (pd.IsBrowsable && !pd.IsReadOnly && pd.SerializationVisibility != DesignerSerializationVisibility.Hidden) { propertyHash[pd.Name] = pd.Converter.ConvertToString(pd.GetValue(obj)); } } catch { } } } return propertyHash; } #endif #endregion } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- Permission.cs
- WorkflowDesignerColors.cs
- EntityStoreSchemaFilterEntry.cs
- SqlDependency.cs
- ISAPIRuntime.cs
- WmlPhoneCallAdapter.cs
- ComplexTypeEmitter.cs
- SpecialTypeDataContract.cs
- ButtonField.cs
- GenericWebPart.cs
- SslStreamSecurityElement.cs
- ThicknessKeyFrameCollection.cs
- BehaviorEditorPart.cs
- TypeGeneratedEventArgs.cs
- DbProviderFactory.cs
- SplitterPanel.cs
- TabControl.cs
- DataGridViewCellLinkedList.cs
- TeredoHelper.cs
- DataGridRelationshipRow.cs
- OdbcStatementHandle.cs
- ComponentResourceKey.cs
- PropertyGrid.cs
- BuildDependencySet.cs
- DebugView.cs
- SerializationAttributes.cs
- WmlTextViewAdapter.cs
- XXXInfos.cs
- RelationshipType.cs
- StorageSetMapping.cs
- CodeArgumentReferenceExpression.cs
- AssemblyInfo.cs
- DataGridViewAutoSizeColumnModeEventArgs.cs
- WebUtil.cs
- ToolStripDropDownClosedEventArgs.cs
- SvcMapFile.cs
- IsolationInterop.cs
- FileSystemWatcher.cs
- PageBuildProvider.cs
- BitmapSizeOptions.cs
- SoapMessage.cs
- InstanceStoreQueryResult.cs
- SqlMetaData.cs
- CodeGen.cs
- SettingsSection.cs
- ToolStripLocationCancelEventArgs.cs
- TimelineClockCollection.cs
- InternalsVisibleToAttribute.cs
- DataGridViewSelectedCellsAccessibleObject.cs
- SqlRetyper.cs
- FontStretch.cs
- Directory.cs
- PackageFilter.cs
- DrawTreeNodeEventArgs.cs
- PeekCompletedEventArgs.cs
- BuildProviderUtils.cs
- Byte.cs
- SmiMetaDataProperty.cs
- EntityParameterCollection.cs
- ThreadInterruptedException.cs
- StateBag.cs
- X509AsymmetricSecurityKey.cs
- NumberFunctions.cs
- PaintEvent.cs
- DateTimeParse.cs
- OleDbReferenceCollection.cs
- RoleGroup.cs
- DBNull.cs
- CharEnumerator.cs
- Encoder.cs
- StatusBarDrawItemEvent.cs
- WindowsTab.cs
- TemplateInstanceAttribute.cs
- DataPagerCommandEventArgs.cs
- TreeNodeCollection.cs
- LabelAutomationPeer.cs
- TreeWalker.cs
- AppSettingsSection.cs
- DefaultAsyncDataDispatcher.cs
- HwndHost.cs
- XmlNamespaceDeclarationsAttribute.cs
- DrawListViewSubItemEventArgs.cs
- XmlAnyAttributeAttribute.cs
- ColorIndependentAnimationStorage.cs
- TemplateParser.cs
- RangeEnumerable.cs
- CancellationTokenRegistration.cs
- AdapterUtil.cs
- ProvidersHelper.cs
- SerTrace.cs
- FixUpCollection.cs
- WasEndpointConfigContainer.cs
- ISAPIApplicationHost.cs
- _FixedSizeReader.cs
- BuiltInExpr.cs
- ConditionalExpression.cs
- DataGridViewRowsRemovedEventArgs.cs
- RayHitTestParameters.cs
- TailPinnedEventArgs.cs
- XAMLParseException.cs