Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / wpf / src / Themes / Aero / Microsoft / Windows / Themes / ListBoxChrome.cs / 1 / ListBoxChrome.cs
//---------------------------------------------------------------------------- // File: ListBoxChrome.cs // // Description: // Implementation of ListBox border in Aero. // // Copyright (C) by Microsoft Corporation. All rights reserved. // //--------------------------------------------------------------------------- using System.Windows.Shapes; using System.Windows.Controls; using System.Diagnostics; using System.Threading; using System.ComponentModel; using System.Windows; using System.Windows.Media; using System.Windows.Media.Animation; using MS.Internal; using System; namespace Microsoft.Windows.Themes { ////// The ListBoxChrome element /// This element is a theme-specific type that is used as an optimization /// for a common complex rendering used in Aero /// /// public sealed class ListBoxChrome : Decorator { #region Constructors static ListBoxChrome() { IsEnabledProperty.OverrideMetadata(typeof(ListBoxChrome), new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.AffectsRender)); } ////// Instantiates a new instance of a ListBoxChrome with no parent element. /// ///public ListBoxChrome() { } #endregion Constructors #region Dynamic Properties /// /// DependencyProperty for public static readonly DependencyProperty BackgroundProperty = Control.BackgroundProperty.AddOwner( typeof(ListBoxChrome), new FrameworkPropertyMetadata( null, FrameworkPropertyMetadataOptions.AffectsRender)); ///property. /// /// The Background property defines the brush used to fill the background of the button. /// public Brush Background { get { return (Brush) GetValue(BackgroundProperty); } set { SetValue(BackgroundProperty, value); } } ////// DependencyProperty for public static readonly DependencyProperty BorderBrushProperty = Border.BorderBrushProperty.AddOwner( typeof(ListBoxChrome), new FrameworkPropertyMetadata( null, FrameworkPropertyMetadataOptions.AffectsRender)); ///property. /// /// The BorderBrush property defines the brush used to draw the outer border. /// public Brush BorderBrush { get { return (Brush) GetValue(BorderBrushProperty); } set { SetValue(BorderBrushProperty, value); } } ////// DependencyProperty for public static readonly DependencyProperty BorderThicknessProperty = Border.BorderThicknessProperty.AddOwner( typeof(ListBoxChrome), new FrameworkPropertyMetadata( new Thickness(1), FrameworkPropertyMetadataOptions.AffectsRender)); ///property. /// /// The BorderThickness property defines the thickness of the border. /// public Thickness BorderThickness { get { return (Thickness)GetValue(BorderThicknessProperty); } set { SetValue(BorderThicknessProperty, value); } } ////// DependencyProperty for public static readonly DependencyProperty RenderMouseOverProperty = DependencyProperty.Register("RenderMouseOver", typeof(bool), typeof(ListBoxChrome), new FrameworkPropertyMetadata( false, new PropertyChangedCallback(OnRenderMouseOverChanged))); ///property. /// /// When true the chrome renders with a mouse over look. /// public bool RenderMouseOver { get { return (bool)GetValue(RenderMouseOverProperty); } set { SetValue(RenderMouseOverProperty, value); } } private static void OnRenderMouseOverChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) { ListBoxChrome chrome = ((ListBoxChrome)o); if (chrome.RenderFocused) { return; } if (chrome.Animates) { if (((bool)e.NewValue)) { if (chrome._localResources == null) { chrome._localResources = new LocalResources(); chrome.InvalidateVisual(); } Duration duration = new Duration(TimeSpan.FromSeconds(0.3)); DoubleAnimation da = new DoubleAnimation(1, duration); chrome.BorderOverlayPen.Brush.BeginAnimation(Brush.OpacityProperty, da); } else if (chrome._localResources == null) { chrome.InvalidateVisual(); } else { Duration duration = new Duration(TimeSpan.FromSeconds(0.2)); DoubleAnimation da = new DoubleAnimation(); da.Duration = duration; chrome.BorderOverlayPen.Brush.BeginAnimation(Brush.OpacityProperty, da); } } else { chrome._localResources = null; chrome.InvalidateVisual(); } } ////// DependencyProperty for public static readonly DependencyProperty RenderFocusedProperty = DependencyProperty.Register("RenderFocused", typeof(bool), typeof(ListBoxChrome), new FrameworkPropertyMetadata( false, new PropertyChangedCallback(OnRenderFocusedChanged))); ///property. /// /// When true the chrome renders with a Focused look. /// public bool RenderFocused { get { return (bool)GetValue(RenderFocusedProperty); } set { SetValue(RenderFocusedProperty, value); } } private static void OnRenderFocusedChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) { ListBoxChrome chrome = ((ListBoxChrome)o); chrome._localResources = null; chrome.InvalidateVisual(); } #endregion Dynamic Properties #region Protected Methods ////// Updates DesiredSize of the ListBoxChrome. Called by parent UIElement. This is the first pass of layout. /// /// Available size is an "upper limit" that the return value should not exceed. ///The ListBoxChrome's desired size. protected override Size MeasureOverride(Size availableSize) { Size desired; Thickness border = BorderThickness; double borderX = border.Left + border.Right; double borderY = border.Top + border.Bottom; // When BorderThickness is 0, draw no border - otherwise add 1 on each side // for inner border if (borderX > 0 || borderY > 0) { borderX += 2.0; borderY += 2.0; } UIElement child = Child; if (child != null) { Size childConstraint = new Size(); bool isWidthTooSmall = (availableSize.Width < borderX); bool isHeightTooSmall = (availableSize.Height < borderY); if (!isWidthTooSmall) { childConstraint.Width = availableSize.Width - borderX; } if (!isHeightTooSmall) { childConstraint.Height = availableSize.Height - borderY; } child.Measure(childConstraint); desired = child.DesiredSize; if (!isWidthTooSmall) { desired.Width += borderX; } if (!isHeightTooSmall) { desired.Height += borderY; } } else { desired = new Size(Math.Min(borderX, availableSize.Width), Math.Min(borderY, availableSize.Height)); } return desired; } ////// ListBoxChrome computes the position of its single child inside child's Margin and calls Arrange /// on the child. /// ////// ListBoxChrome basically inflates the desired size of its one child by 2 on all four sides /// /// Size the ContentPresenter will assume. protected override Size ArrangeOverride(Size finalSize) { Rect childArrangeRect = new Rect(); Thickness border = BorderThickness; double borderX = border.Left + border.Right; double borderY = border.Top + border.Bottom; // When BorderThickness is 0, draw no border - otherwise add 1 on each side // for inner border if (borderX > 0 || borderY > 0) { border.Left += 1.0; border.Top += 1.0; borderX += 2.0; borderY += 2.0; } if ((finalSize.Width > borderX) && (finalSize.Height > borderY)) { childArrangeRect.X = border.Left; childArrangeRect.Y = border.Top; childArrangeRect.Width = finalSize.Width - borderX; childArrangeRect.Height = finalSize.Height - borderY; } if (Child != null) { Child.Arrange(childArrangeRect); } return finalSize; } ////// Render callback. /// protected override void OnRender(DrawingContext dc) { Rect bounds = new Rect(0, 0, ActualWidth, ActualHeight); Thickness border = BorderThickness; double borderX = border.Left + border.Right; double borderY = border.Top + border.Bottom; // ListBoxChrome is rendered with a border of BorderThickness // Inside this is the Background. Inside the background // is the Background overlay for disabled controls which // is offset by 1 px. bool isSimpleBorder = border.Left == 1.0 && border.Right == 1.0 && border.Top == 1.0 && border.Bottom == 1.0; double innerBorderThickness = (borderX == 0.0 && borderY == 0.0) ? 0.0 : 1.0; double innerBorderThickness2 = 2 * innerBorderThickness; if ((bounds.Width > borderX) && (bounds.Height > borderY)) { Rect backgroundRect = new Rect(bounds.Left + border.Left, bounds.Top + border.Top, bounds.Width - borderX, bounds.Height - borderY); Brush fill = Background; // Draw Background if (fill != null) dc.DrawRectangle(fill, null, backgroundRect); // Draw Background Overlay inset by 1px from edge of main border if ((bounds.Width > borderX + innerBorderThickness2) && (bounds.Height > borderY + innerBorderThickness2)) { backgroundRect = new Rect(bounds.Left + border.Left + innerBorderThickness, bounds.Top + border.Top + innerBorderThickness, bounds.Width - borderX - innerBorderThickness2, bounds.Height - borderY - innerBorderThickness2); // Draw BackgroundOverlay fill = BackgroundOverlay; if (fill != null) dc.DrawRoundedRectangle(fill, null, backgroundRect, 1, 1); } } // Draw borders // innerBorderThickness is 0 when the listbox border is 0 if (innerBorderThickness > 0) { // Draw Main border if ((bounds.Width >= borderX) && (bounds.Height >= borderY)) { if (isSimpleBorder) { Rect rect = new Rect(bounds.Left + 0.5, bounds.Top + 0.5, bounds.Width - 1.0, bounds.Height - 1.0); Pen pen = GetBorderPen(BorderBrush); Pen overlayPen = BorderOverlayPen; if (pen != null) dc.DrawRoundedRectangle(null, pen, rect, 1.0, 1.0); if (overlayPen != null) dc.DrawRoundedRectangle(null, overlayPen, rect, 1.0, 1.0); } else { Geometry geometry = GetBorderGeometry(border, bounds); if (BorderBrush != null) dc.DrawGeometry(BorderBrush, null, geometry); } } } } #endregion #region Private Properties // // This property // 1. Finds the correct initial size for the _effectiveValues store on the current DependencyObject // 2. This is a performance optimization // internal override int EffectiveValuesInitialSize { get { return 9; } } private bool Animates { get { return SystemParameters.ClientAreaAnimation && RenderCapability.Tier > 0 && IsEnabled; } } private static Pen GetBorderPen(Brush border) { Pen pen = null; if (border != null) { if (_commonBorderPen == null) // Common case, if non-null, avoid the lock { lock (_resourceAccess) // If non-null, lock to create the pen for thread safety { if (_commonBorderPen == null) // Check again in case _pen was created within the last line { // Assume that the first render of Button uses the most common brush for the app. // This breaks down if (a) the first Button is disabled, (b) the first Button is // customized, or (c) ListBoxChrome becomes more broadly used than just on Button. // // If these cons sufficiently weaken the effectiveness of this cache, then we need // to build a larger brush-to-pen mapping cache. // If the brush is not already frozen, we need to create our own // copy. Otherwise we will inadvertently freeze the user's // BorderBrush when we freeze the pen below. if (!border.IsFrozen && border.CanFreeze) { border = border.Clone(); border.Freeze(); } Pen commonPen = new Pen(border, 1); if (commonPen.CanFreeze) { // Only save frozen pens, some brushes such as VisualBrush // can not be frozen commonPen.Freeze(); _commonBorderPen = commonPen; } } } } if (_commonBorderPen != null && border == _commonBorderPen.Brush) { pen = _commonBorderPen; } else { if (!border.IsFrozen && border.CanFreeze) { border = border.Clone(); border.Freeze(); } pen = new Pen(border, 1); if (pen.CanFreeze) { pen.Freeze(); } } } return pen; } private static Geometry GetBorderGeometry(Thickness thickness, Rect bounds) { PathFigure borderFigure = new PathFigure(); borderFigure.StartPoint = new Point(bounds.Left, bounds.Top); borderFigure.Segments.Add(new LineSegment(new Point(bounds.Left, bounds.Bottom), false)); borderFigure.Segments.Add(new LineSegment(new Point(bounds.Right, bounds.Bottom), false)); borderFigure.Segments.Add(new LineSegment(new Point(bounds.Right, bounds.Top), false)); borderFigure.IsClosed = true; PathGeometry borderGeometry = new PathGeometry(); borderGeometry.Figures.Add(borderFigure); borderFigure = new PathFigure(); borderFigure.StartPoint = new Point(bounds.Left + thickness.Left, bounds.Top + thickness.Top); borderFigure.Segments.Add(new LineSegment(new Point(bounds.Left + thickness.Left, bounds.Bottom - thickness.Bottom), false)); borderFigure.Segments.Add(new LineSegment(new Point(bounds.Right - thickness.Right, bounds.Bottom - thickness.Bottom), false)); borderFigure.Segments.Add(new LineSegment(new Point(bounds.Right - thickness.Right, bounds.Top + thickness.Top), false)); borderFigure.IsClosed = true; borderGeometry.Figures.Add(borderFigure); return borderGeometry; } private static SolidColorBrush CommonDisabledBackgroundOverlay { get { if (_commonDisabledBackgroundOverlay == null) { lock (_resourceAccess) { if (_commonDisabledBackgroundOverlay == null) { SolidColorBrush temp = new SolidColorBrush(Color.FromRgb(0xF4, 0xF4, 0xF4)); temp.Freeze(); // Static field must not be set until the local has been frozen _commonDisabledBackgroundOverlay = temp; } } } return _commonDisabledBackgroundOverlay; } } private static Pen CommonHoverBorderOverlay { get { if (_commonHoverBorderOverlay == null) { lock (_resourceAccess) { if (_commonHoverBorderOverlay == null) { Pen temp = new Pen(); temp.Thickness = 1; LinearGradientBrush brush = new LinearGradientBrush(); brush.StartPoint = new Point(0, 0); brush.EndPoint = new Point(0, 20); brush.MappingMode = BrushMappingMode.Absolute; brush.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0x57, 0x94, 0xBF), 0.05)); brush.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xB7, 0xD5, 0xEA), 0.07)); brush.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xC7, 0xE2, 0xF1), 1)); temp.Brush = brush; temp.Freeze(); _commonHoverBorderOverlay = temp; } } } return _commonHoverBorderOverlay; } } private static Pen CommonFocusedBorderOverlay { get { if (_commonFocusedBorderOverlay == null) { lock (_resourceAccess) { if (_commonFocusedBorderOverlay == null) { Pen temp = new Pen(); temp.Thickness = 1; LinearGradientBrush brush = new LinearGradientBrush(); brush.StartPoint = new Point(0, 0); brush.EndPoint = new Point(0, 20); brush.MappingMode = BrushMappingMode.Absolute; brush.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0x3D, 0x7B, 0xAD), 0.05)); brush.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xA4, 0xC9, 0xE3), 0.07)); brush.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xB7, 0xD9, 0xED), 1)); temp.Brush = brush; temp.Freeze(); _commonFocusedBorderOverlay = temp; } } } return _commonFocusedBorderOverlay; } } private static Pen CommonDisabledBorderOverlay { get { if (_commonDisabledBorderOverlay == null) { lock (_resourceAccess) { if (_commonDisabledBorderOverlay == null) { Pen temp = new Pen(); temp.Thickness = 1; temp.Brush = new SolidColorBrush(Color.FromRgb(0xAD, 0xB2, 0xB5)); temp.Freeze(); _commonDisabledBorderOverlay = temp; } } } return _commonDisabledBorderOverlay; } } private Brush BackgroundOverlay { get { if (!IsEnabled) { return CommonDisabledBackgroundOverlay; } else { return null; } } } private Pen BorderOverlayPen { get { if (!IsEnabled) { return CommonDisabledBorderOverlay; } if (_localResources != null) { if (_localResources.BorderOverlayPen == null) { _localResources.BorderOverlayPen = CommonHoverBorderOverlay.Clone(); _localResources.BorderOverlayPen.Brush.Opacity = 0; } return _localResources.BorderOverlayPen; } if (RenderFocused) { return CommonFocusedBorderOverlay; } else if (RenderMouseOver) { return CommonHoverBorderOverlay; } else { return null; } } } private static SolidColorBrush _commonDisabledBackgroundOverlay; private static Pen _commonBorderPen; private static Pen _commonDisabledBorderOverlay; private static Pen _commonHoverBorderOverlay; private static Pen _commonFocusedBorderOverlay; private static object _resourceAccess = new object(); // Per instance resources private LocalResources _localResources; private class LocalResources { public Pen BorderOverlayPen; } #endregion } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. //---------------------------------------------------------------------------- // File: ListBoxChrome.cs // // Description: // Implementation of ListBox border in Aero. // // Copyright (C) by Microsoft Corporation. All rights reserved. // //--------------------------------------------------------------------------- using System.Windows.Shapes; using System.Windows.Controls; using System.Diagnostics; using System.Threading; using System.ComponentModel; using System.Windows; using System.Windows.Media; using System.Windows.Media.Animation; using MS.Internal; using System; namespace Microsoft.Windows.Themes { ////// The ListBoxChrome element /// This element is a theme-specific type that is used as an optimization /// for a common complex rendering used in Aero /// /// public sealed class ListBoxChrome : Decorator { #region Constructors static ListBoxChrome() { IsEnabledProperty.OverrideMetadata(typeof(ListBoxChrome), new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.AffectsRender)); } ////// Instantiates a new instance of a ListBoxChrome with no parent element. /// ///public ListBoxChrome() { } #endregion Constructors #region Dynamic Properties /// /// DependencyProperty for public static readonly DependencyProperty BackgroundProperty = Control.BackgroundProperty.AddOwner( typeof(ListBoxChrome), new FrameworkPropertyMetadata( null, FrameworkPropertyMetadataOptions.AffectsRender)); ///property. /// /// The Background property defines the brush used to fill the background of the button. /// public Brush Background { get { return (Brush) GetValue(BackgroundProperty); } set { SetValue(BackgroundProperty, value); } } ////// DependencyProperty for public static readonly DependencyProperty BorderBrushProperty = Border.BorderBrushProperty.AddOwner( typeof(ListBoxChrome), new FrameworkPropertyMetadata( null, FrameworkPropertyMetadataOptions.AffectsRender)); ///property. /// /// The BorderBrush property defines the brush used to draw the outer border. /// public Brush BorderBrush { get { return (Brush) GetValue(BorderBrushProperty); } set { SetValue(BorderBrushProperty, value); } } ////// DependencyProperty for public static readonly DependencyProperty BorderThicknessProperty = Border.BorderThicknessProperty.AddOwner( typeof(ListBoxChrome), new FrameworkPropertyMetadata( new Thickness(1), FrameworkPropertyMetadataOptions.AffectsRender)); ///property. /// /// The BorderThickness property defines the thickness of the border. /// public Thickness BorderThickness { get { return (Thickness)GetValue(BorderThicknessProperty); } set { SetValue(BorderThicknessProperty, value); } } ////// DependencyProperty for public static readonly DependencyProperty RenderMouseOverProperty = DependencyProperty.Register("RenderMouseOver", typeof(bool), typeof(ListBoxChrome), new FrameworkPropertyMetadata( false, new PropertyChangedCallback(OnRenderMouseOverChanged))); ///property. /// /// When true the chrome renders with a mouse over look. /// public bool RenderMouseOver { get { return (bool)GetValue(RenderMouseOverProperty); } set { SetValue(RenderMouseOverProperty, value); } } private static void OnRenderMouseOverChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) { ListBoxChrome chrome = ((ListBoxChrome)o); if (chrome.RenderFocused) { return; } if (chrome.Animates) { if (((bool)e.NewValue)) { if (chrome._localResources == null) { chrome._localResources = new LocalResources(); chrome.InvalidateVisual(); } Duration duration = new Duration(TimeSpan.FromSeconds(0.3)); DoubleAnimation da = new DoubleAnimation(1, duration); chrome.BorderOverlayPen.Brush.BeginAnimation(Brush.OpacityProperty, da); } else if (chrome._localResources == null) { chrome.InvalidateVisual(); } else { Duration duration = new Duration(TimeSpan.FromSeconds(0.2)); DoubleAnimation da = new DoubleAnimation(); da.Duration = duration; chrome.BorderOverlayPen.Brush.BeginAnimation(Brush.OpacityProperty, da); } } else { chrome._localResources = null; chrome.InvalidateVisual(); } } ////// DependencyProperty for public static readonly DependencyProperty RenderFocusedProperty = DependencyProperty.Register("RenderFocused", typeof(bool), typeof(ListBoxChrome), new FrameworkPropertyMetadata( false, new PropertyChangedCallback(OnRenderFocusedChanged))); ///property. /// /// When true the chrome renders with a Focused look. /// public bool RenderFocused { get { return (bool)GetValue(RenderFocusedProperty); } set { SetValue(RenderFocusedProperty, value); } } private static void OnRenderFocusedChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) { ListBoxChrome chrome = ((ListBoxChrome)o); chrome._localResources = null; chrome.InvalidateVisual(); } #endregion Dynamic Properties #region Protected Methods ////// Updates DesiredSize of the ListBoxChrome. Called by parent UIElement. This is the first pass of layout. /// /// Available size is an "upper limit" that the return value should not exceed. ///The ListBoxChrome's desired size. protected override Size MeasureOverride(Size availableSize) { Size desired; Thickness border = BorderThickness; double borderX = border.Left + border.Right; double borderY = border.Top + border.Bottom; // When BorderThickness is 0, draw no border - otherwise add 1 on each side // for inner border if (borderX > 0 || borderY > 0) { borderX += 2.0; borderY += 2.0; } UIElement child = Child; if (child != null) { Size childConstraint = new Size(); bool isWidthTooSmall = (availableSize.Width < borderX); bool isHeightTooSmall = (availableSize.Height < borderY); if (!isWidthTooSmall) { childConstraint.Width = availableSize.Width - borderX; } if (!isHeightTooSmall) { childConstraint.Height = availableSize.Height - borderY; } child.Measure(childConstraint); desired = child.DesiredSize; if (!isWidthTooSmall) { desired.Width += borderX; } if (!isHeightTooSmall) { desired.Height += borderY; } } else { desired = new Size(Math.Min(borderX, availableSize.Width), Math.Min(borderY, availableSize.Height)); } return desired; } ////// ListBoxChrome computes the position of its single child inside child's Margin and calls Arrange /// on the child. /// ////// ListBoxChrome basically inflates the desired size of its one child by 2 on all four sides /// /// Size the ContentPresenter will assume. protected override Size ArrangeOverride(Size finalSize) { Rect childArrangeRect = new Rect(); Thickness border = BorderThickness; double borderX = border.Left + border.Right; double borderY = border.Top + border.Bottom; // When BorderThickness is 0, draw no border - otherwise add 1 on each side // for inner border if (borderX > 0 || borderY > 0) { border.Left += 1.0; border.Top += 1.0; borderX += 2.0; borderY += 2.0; } if ((finalSize.Width > borderX) && (finalSize.Height > borderY)) { childArrangeRect.X = border.Left; childArrangeRect.Y = border.Top; childArrangeRect.Width = finalSize.Width - borderX; childArrangeRect.Height = finalSize.Height - borderY; } if (Child != null) { Child.Arrange(childArrangeRect); } return finalSize; } ////// Render callback. /// protected override void OnRender(DrawingContext dc) { Rect bounds = new Rect(0, 0, ActualWidth, ActualHeight); Thickness border = BorderThickness; double borderX = border.Left + border.Right; double borderY = border.Top + border.Bottom; // ListBoxChrome is rendered with a border of BorderThickness // Inside this is the Background. Inside the background // is the Background overlay for disabled controls which // is offset by 1 px. bool isSimpleBorder = border.Left == 1.0 && border.Right == 1.0 && border.Top == 1.0 && border.Bottom == 1.0; double innerBorderThickness = (borderX == 0.0 && borderY == 0.0) ? 0.0 : 1.0; double innerBorderThickness2 = 2 * innerBorderThickness; if ((bounds.Width > borderX) && (bounds.Height > borderY)) { Rect backgroundRect = new Rect(bounds.Left + border.Left, bounds.Top + border.Top, bounds.Width - borderX, bounds.Height - borderY); Brush fill = Background; // Draw Background if (fill != null) dc.DrawRectangle(fill, null, backgroundRect); // Draw Background Overlay inset by 1px from edge of main border if ((bounds.Width > borderX + innerBorderThickness2) && (bounds.Height > borderY + innerBorderThickness2)) { backgroundRect = new Rect(bounds.Left + border.Left + innerBorderThickness, bounds.Top + border.Top + innerBorderThickness, bounds.Width - borderX - innerBorderThickness2, bounds.Height - borderY - innerBorderThickness2); // Draw BackgroundOverlay fill = BackgroundOverlay; if (fill != null) dc.DrawRoundedRectangle(fill, null, backgroundRect, 1, 1); } } // Draw borders // innerBorderThickness is 0 when the listbox border is 0 if (innerBorderThickness > 0) { // Draw Main border if ((bounds.Width >= borderX) && (bounds.Height >= borderY)) { if (isSimpleBorder) { Rect rect = new Rect(bounds.Left + 0.5, bounds.Top + 0.5, bounds.Width - 1.0, bounds.Height - 1.0); Pen pen = GetBorderPen(BorderBrush); Pen overlayPen = BorderOverlayPen; if (pen != null) dc.DrawRoundedRectangle(null, pen, rect, 1.0, 1.0); if (overlayPen != null) dc.DrawRoundedRectangle(null, overlayPen, rect, 1.0, 1.0); } else { Geometry geometry = GetBorderGeometry(border, bounds); if (BorderBrush != null) dc.DrawGeometry(BorderBrush, null, geometry); } } } } #endregion #region Private Properties // // This property // 1. Finds the correct initial size for the _effectiveValues store on the current DependencyObject // 2. This is a performance optimization // internal override int EffectiveValuesInitialSize { get { return 9; } } private bool Animates { get { return SystemParameters.ClientAreaAnimation && RenderCapability.Tier > 0 && IsEnabled; } } private static Pen GetBorderPen(Brush border) { Pen pen = null; if (border != null) { if (_commonBorderPen == null) // Common case, if non-null, avoid the lock { lock (_resourceAccess) // If non-null, lock to create the pen for thread safety { if (_commonBorderPen == null) // Check again in case _pen was created within the last line { // Assume that the first render of Button uses the most common brush for the app. // This breaks down if (a) the first Button is disabled, (b) the first Button is // customized, or (c) ListBoxChrome becomes more broadly used than just on Button. // // If these cons sufficiently weaken the effectiveness of this cache, then we need // to build a larger brush-to-pen mapping cache. // If the brush is not already frozen, we need to create our own // copy. Otherwise we will inadvertently freeze the user's // BorderBrush when we freeze the pen below. if (!border.IsFrozen && border.CanFreeze) { border = border.Clone(); border.Freeze(); } Pen commonPen = new Pen(border, 1); if (commonPen.CanFreeze) { // Only save frozen pens, some brushes such as VisualBrush // can not be frozen commonPen.Freeze(); _commonBorderPen = commonPen; } } } } if (_commonBorderPen != null && border == _commonBorderPen.Brush) { pen = _commonBorderPen; } else { if (!border.IsFrozen && border.CanFreeze) { border = border.Clone(); border.Freeze(); } pen = new Pen(border, 1); if (pen.CanFreeze) { pen.Freeze(); } } } return pen; } private static Geometry GetBorderGeometry(Thickness thickness, Rect bounds) { PathFigure borderFigure = new PathFigure(); borderFigure.StartPoint = new Point(bounds.Left, bounds.Top); borderFigure.Segments.Add(new LineSegment(new Point(bounds.Left, bounds.Bottom), false)); borderFigure.Segments.Add(new LineSegment(new Point(bounds.Right, bounds.Bottom), false)); borderFigure.Segments.Add(new LineSegment(new Point(bounds.Right, bounds.Top), false)); borderFigure.IsClosed = true; PathGeometry borderGeometry = new PathGeometry(); borderGeometry.Figures.Add(borderFigure); borderFigure = new PathFigure(); borderFigure.StartPoint = new Point(bounds.Left + thickness.Left, bounds.Top + thickness.Top); borderFigure.Segments.Add(new LineSegment(new Point(bounds.Left + thickness.Left, bounds.Bottom - thickness.Bottom), false)); borderFigure.Segments.Add(new LineSegment(new Point(bounds.Right - thickness.Right, bounds.Bottom - thickness.Bottom), false)); borderFigure.Segments.Add(new LineSegment(new Point(bounds.Right - thickness.Right, bounds.Top + thickness.Top), false)); borderFigure.IsClosed = true; borderGeometry.Figures.Add(borderFigure); return borderGeometry; } private static SolidColorBrush CommonDisabledBackgroundOverlay { get { if (_commonDisabledBackgroundOverlay == null) { lock (_resourceAccess) { if (_commonDisabledBackgroundOverlay == null) { SolidColorBrush temp = new SolidColorBrush(Color.FromRgb(0xF4, 0xF4, 0xF4)); temp.Freeze(); // Static field must not be set until the local has been frozen _commonDisabledBackgroundOverlay = temp; } } } return _commonDisabledBackgroundOverlay; } } private static Pen CommonHoverBorderOverlay { get { if (_commonHoverBorderOverlay == null) { lock (_resourceAccess) { if (_commonHoverBorderOverlay == null) { Pen temp = new Pen(); temp.Thickness = 1; LinearGradientBrush brush = new LinearGradientBrush(); brush.StartPoint = new Point(0, 0); brush.EndPoint = new Point(0, 20); brush.MappingMode = BrushMappingMode.Absolute; brush.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0x57, 0x94, 0xBF), 0.05)); brush.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xB7, 0xD5, 0xEA), 0.07)); brush.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xC7, 0xE2, 0xF1), 1)); temp.Brush = brush; temp.Freeze(); _commonHoverBorderOverlay = temp; } } } return _commonHoverBorderOverlay; } } private static Pen CommonFocusedBorderOverlay { get { if (_commonFocusedBorderOverlay == null) { lock (_resourceAccess) { if (_commonFocusedBorderOverlay == null) { Pen temp = new Pen(); temp.Thickness = 1; LinearGradientBrush brush = new LinearGradientBrush(); brush.StartPoint = new Point(0, 0); brush.EndPoint = new Point(0, 20); brush.MappingMode = BrushMappingMode.Absolute; brush.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0x3D, 0x7B, 0xAD), 0.05)); brush.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xA4, 0xC9, 0xE3), 0.07)); brush.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xB7, 0xD9, 0xED), 1)); temp.Brush = brush; temp.Freeze(); _commonFocusedBorderOverlay = temp; } } } return _commonFocusedBorderOverlay; } } private static Pen CommonDisabledBorderOverlay { get { if (_commonDisabledBorderOverlay == null) { lock (_resourceAccess) { if (_commonDisabledBorderOverlay == null) { Pen temp = new Pen(); temp.Thickness = 1; temp.Brush = new SolidColorBrush(Color.FromRgb(0xAD, 0xB2, 0xB5)); temp.Freeze(); _commonDisabledBorderOverlay = temp; } } } return _commonDisabledBorderOverlay; } } private Brush BackgroundOverlay { get { if (!IsEnabled) { return CommonDisabledBackgroundOverlay; } else { return null; } } } private Pen BorderOverlayPen { get { if (!IsEnabled) { return CommonDisabledBorderOverlay; } if (_localResources != null) { if (_localResources.BorderOverlayPen == null) { _localResources.BorderOverlayPen = CommonHoverBorderOverlay.Clone(); _localResources.BorderOverlayPen.Brush.Opacity = 0; } return _localResources.BorderOverlayPen; } if (RenderFocused) { return CommonFocusedBorderOverlay; } else if (RenderMouseOver) { return CommonHoverBorderOverlay; } else { return null; } } } private static SolidColorBrush _commonDisabledBackgroundOverlay; private static Pen _commonBorderPen; private static Pen _commonDisabledBorderOverlay; private static Pen _commonHoverBorderOverlay; private static Pen _commonFocusedBorderOverlay; private static object _resourceAccess = new object(); // Per instance resources private LocalResources _localResources; private class LocalResources { public Pen BorderOverlayPen; } #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
- TimeZone.cs
- CommonObjectSecurity.cs
- CollectionsUtil.cs
- Directory.cs
- Compiler.cs
- SecondaryViewProvider.cs
- _NetRes.cs
- RootProfilePropertySettingsCollection.cs
- ReaderWriterLock.cs
- ExtractedStateEntry.cs
- AutoResetEvent.cs
- TableCellCollection.cs
- ProgressChangedEventArgs.cs
- FileDataSourceCache.cs
- AnonymousIdentificationModule.cs
- CardSpaceSelector.cs
- StringInfo.cs
- ImmutablePropertyDescriptorGridEntry.cs
- BitmapFrame.cs
- ValueType.cs
- XmlWrappingWriter.cs
- Stack.cs
- TimeSpan.cs
- COMException.cs
- TabControl.cs
- SmiSettersStream.cs
- MultilineStringEditor.cs
- DataSvcMapFileSerializer.cs
- NativeMethods.cs
- SqlOuterApplyReducer.cs
- DataGridCell.cs
- QueryExpr.cs
- ObjectDataSourceDisposingEventArgs.cs
- UnmanagedMarshal.cs
- ArithmeticException.cs
- XmlNamespaceMappingCollection.cs
- OutputCacheSection.cs
- ButtonBase.cs
- Attribute.cs
- HwndSourceKeyboardInputSite.cs
- SqlCacheDependency.cs
- RawUIStateInputReport.cs
- ValidatorCompatibilityHelper.cs
- FixedPageProcessor.cs
- ContextStaticAttribute.cs
- TagNameToTypeMapper.cs
- TypeConverterHelper.cs
- ImpersonationContext.cs
- ActivationArguments.cs
- LinkButton.cs
- BrowserInteropHelper.cs
- RSAPKCS1SignatureDeformatter.cs
- DependentList.cs
- BitmapEffect.cs
- MenuItemStyleCollectionEditor.cs
- DrawingImage.cs
- InteropBitmapSource.cs
- ClientRolePrincipal.cs
- RuleRef.cs
- Content.cs
- DataGridSortCommandEventArgs.cs
- DataRecordInternal.cs
- ReliableChannelListener.cs
- _NativeSSPI.cs
- EmptyControlCollection.cs
- MiniCustomAttributeInfo.cs
- SupportingTokenDuplexChannel.cs
- ChangeConflicts.cs
- MatrixTransform.cs
- DecoderFallback.cs
- PeerNameResolver.cs
- WorkflowMessageEventArgs.cs
- XmlSubtreeReader.cs
- GetIsBrowserClientRequest.cs
- ToolStripDropDownButton.cs
- BitmapPalette.cs
- Operator.cs
- TypeLoadException.cs
- ToggleButtonAutomationPeer.cs
- ProjectionPlanCompiler.cs
- ConfigViewGenerator.cs
- FunctionImportElement.cs
- Exceptions.cs
- Point3DKeyFrameCollection.cs
- DropDownList.cs
- ValidatorAttribute.cs
- DecimalKeyFrameCollection.cs
- InkCanvasInnerCanvas.cs
- CustomSignedXml.cs
- SendMessageRecord.cs
- ProcessHostConfigUtils.cs
- SHA384Managed.cs
- Message.cs
- RemoteX509Token.cs
- TagPrefixAttribute.cs
- VBIdentifierDesigner.xaml.cs
- EntityDataSourceDataSelection.cs
- PageContentCollection.cs
- CounterSetInstanceCounterDataSet.cs
- TextOnlyOutput.cs