Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Framework / System / Windows / Controls / Primitives / DataGridColumnHeader.cs / 1407647 / DataGridColumnHeader.cs
//----------------------------------------------------------------------------
//
// Copyright (C) Microsoft Corporation. All rights reserved.
//
//---------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Windows;
using System.Windows.Automation.Peers;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using MS.Internal;
namespace System.Windows.Controls.Primitives
{
///
/// Container for the Column header object. This is instantiated by the DataGridColumnHeadersPresenter.
///
[TemplatePart(Name = "PART_LeftHeaderGripper", Type = typeof(Thumb))]
[TemplatePart(Name = "PART_RightHeaderGripper", Type = typeof(Thumb))]
public class DataGridColumnHeader : ButtonBase, IProvideDataGridColumn
{
#region Constructors
static DataGridColumnHeader()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(DataGridColumnHeader), new FrameworkPropertyMetadata(typeof(DataGridColumnHeader)));
ContentProperty.OverrideMetadata(typeof(DataGridColumnHeader), new FrameworkPropertyMetadata(OnNotifyPropertyChanged, OnCoerceContent));
ContentTemplateProperty.OverrideMetadata(typeof(DataGridColumnHeader), new FrameworkPropertyMetadata(null, OnNotifyPropertyChanged, OnCoerceContentTemplate));
ContentTemplateSelectorProperty.OverrideMetadata(typeof(DataGridColumnHeader), new FrameworkPropertyMetadata(null, OnNotifyPropertyChanged, OnCoerceContentTemplateSelector));
ContentStringFormatProperty.OverrideMetadata(typeof(DataGridColumnHeader), new FrameworkPropertyMetadata(null, OnNotifyPropertyChanged, OnCoerceStringFormat));
StyleProperty.OverrideMetadata(typeof(DataGridColumnHeader), new FrameworkPropertyMetadata(null, OnNotifyPropertyChanged, OnCoerceStyle));
HeightProperty.OverrideMetadata(typeof(DataGridColumnHeader), new FrameworkPropertyMetadata(OnNotifyPropertyChanged, OnCoerceHeight));
FocusableProperty.OverrideMetadata(typeof(DataGridColumnHeader), new FrameworkPropertyMetadata(false));
ClipProperty.OverrideMetadata(typeof(DataGridColumnHeader), new FrameworkPropertyMetadata(null, OnCoerceClip));
}
///
/// Instantiates a new instance of this class.
///
public DataGridColumnHeader()
{
_tracker = new ContainerTracking(this);
}
#endregion
#region Public API
///
/// The Column associated with this DataGridColumnHeader.
///
public DataGridColumn Column
{
get
{
return _column;
}
}
///
/// Property that indicates the brush to use when drawing seperators between headers.
///
public Brush SeparatorBrush
{
get { return (Brush)GetValue(SeparatorBrushProperty); }
set { SetValue(SeparatorBrushProperty, value); }
}
///
/// DependencyProperty for SeperatorBrush.
///
public static readonly DependencyProperty SeparatorBrushProperty =
DependencyProperty.Register("SeparatorBrush", typeof(Brush), typeof(DataGridColumnHeader), new FrameworkPropertyMetadata(null));
///
/// Property that indicates the Visibility for the header seperators.
///
public Visibility SeparatorVisibility
{
get { return (Visibility)GetValue(SeparatorVisibilityProperty); }
set { SetValue(SeparatorVisibilityProperty, value); }
}
///
/// DependencyProperty for SeperatorBrush.
///
public static readonly DependencyProperty SeparatorVisibilityProperty =
DependencyProperty.Register("SeparatorVisibility", typeof(Visibility), typeof(DataGridColumnHeader), new FrameworkPropertyMetadata(Visibility.Visible));
#endregion
#region Column Header Generation
///
/// Prepares a column header to be used. Sets up the association between the column header and its column.
///
internal void PrepareColumnHeader(object item, DataGridColumn column)
{
Debug.Assert(column != null, "This header must have been generated with for a particular column");
Debug.Assert(column.Header == item, "The data item for a ColumnHeader is the Header property of a column");
_column = column;
TabIndex = column.DisplayIndex;
DataGridHelper.TransferProperty(this, ContentProperty);
DataGridHelper.TransferProperty(this, ContentTemplateProperty);
DataGridHelper.TransferProperty(this, ContentTemplateSelectorProperty);
DataGridHelper.TransferProperty(this, ContentStringFormatProperty);
DataGridHelper.TransferProperty(this, StyleProperty);
DataGridHelper.TransferProperty(this, HeightProperty);
CoerceValue(CanUserSortProperty);
CoerceValue(SortDirectionProperty);
CoerceValue(IsFrozenProperty);
CoerceValue(ClipProperty);
CoerceValue(DisplayIndexProperty);
}
internal void ClearHeader()
{
_column = null;
}
///
/// Used by the DataGridRowGenerator owner to send notifications to the cell container.
///
internal ContainerTracking Tracker
{
get { return _tracker; }
}
#endregion
#region Resize Gripper
///
/// DependencyPropertyKey for DisplayIndex property
///
private static readonly DependencyPropertyKey DisplayIndexPropertyKey =
DependencyProperty.RegisterReadOnly(
"DisplayIndex",
typeof(int),
typeof(DataGridColumnHeader),
new FrameworkPropertyMetadata(-1, new PropertyChangedCallback(OnDisplayIndexChanged), new CoerceValueCallback(OnCoerceDisplayIndex)));
///
/// The DependencyProperty for the DisplayIndex property.
///
public static readonly DependencyProperty DisplayIndexProperty = DisplayIndexPropertyKey.DependencyProperty;
///
/// The property which represents the displayindex of the column corresponding to this header
///
public int DisplayIndex
{
get { return (int)GetValue(DisplayIndexProperty); }
}
///
/// Coercion callback for DisplayIndex property
///
private static object OnCoerceDisplayIndex(DependencyObject d, object baseValue)
{
DataGridColumnHeader header = (DataGridColumnHeader)d;
DataGridColumn column = header.Column;
if (column != null)
{
return column.DisplayIndex;
}
return -1;
}
///
/// Property changed call back for DisplayIndex property.
/// Sets the visibility of resize grippers accordingly
///
///
///
private static void OnDisplayIndexChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
DataGridColumnHeader header = (DataGridColumnHeader)d;
DataGridColumn column = header.Column;
if (column != null)
{
DataGrid dataGrid = column.DataGridOwner;
if (dataGrid != null)
{
header.SetLeftGripperVisibility();
DataGridColumnHeader nextColumnHeader = dataGrid.ColumnHeaderFromDisplayIndex(header.DisplayIndex + 1);
if (nextColumnHeader != null)
{
nextColumnHeader.SetLeftGripperVisibility(column.CanUserResize);
}
}
}
}
///
/// Override for FrameworkElement.OnApplyTemplate
///
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
HookupGripperEvents();
}
///
/// Find grippers and register drag events
///
/// The default style for DataGridHeader is
/// +-------------------------------+
/// +---------+ +---------+
/// + Gripper + Header + Gripper +
/// + + + +
/// +---------+ +---------+
/// +-------------------------------+
///
/// The reason we have two grippers is we can't extend the right gripper to straddle the line between two
/// headers; the header to the right would render on top of it.
/// We resize a column by grabbing the gripper to the right; the leftmost gripper thus adjusts the width of
/// the column to its left.
///
private void HookupGripperEvents()
{
UnhookGripperEvents();
_leftGripper = GetTemplateChild(LeftHeaderGripperTemplateName) as Thumb;
_rightGripper = GetTemplateChild(RightHeaderGripperTemplateName) as Thumb;
if (_leftGripper != null)
{
_leftGripper.DragStarted += new DragStartedEventHandler(OnColumnHeaderGripperDragStarted);
_leftGripper.DragDelta += new DragDeltaEventHandler(OnColumnHeaderResize);
_leftGripper.DragCompleted += new DragCompletedEventHandler(OnColumnHeaderGripperDragCompleted);
_leftGripper.MouseDoubleClick += new MouseButtonEventHandler(OnGripperDoubleClicked);
SetLeftGripperVisibility();
}
if (_rightGripper != null)
{
_rightGripper.DragStarted += new DragStartedEventHandler(OnColumnHeaderGripperDragStarted);
_rightGripper.DragDelta += new DragDeltaEventHandler(OnColumnHeaderResize);
_rightGripper.DragCompleted += new DragCompletedEventHandler(OnColumnHeaderGripperDragCompleted);
_rightGripper.MouseDoubleClick += new MouseButtonEventHandler(OnGripperDoubleClicked);
SetRightGripperVisibility();
}
}
///
/// Clear gripper event
///
private void UnhookGripperEvents()
{
if (_leftGripper != null)
{
_leftGripper.DragStarted -= new DragStartedEventHandler(OnColumnHeaderGripperDragStarted);
_leftGripper.DragDelta -= new DragDeltaEventHandler(OnColumnHeaderResize);
_leftGripper.DragCompleted -= new DragCompletedEventHandler(OnColumnHeaderGripperDragCompleted);
_leftGripper.MouseDoubleClick -= new MouseButtonEventHandler(OnGripperDoubleClicked);
_leftGripper = null;
}
if (_rightGripper != null)
{
_rightGripper.DragStarted -= new DragStartedEventHandler(OnColumnHeaderGripperDragStarted);
_rightGripper.DragDelta -= new DragDeltaEventHandler(OnColumnHeaderResize);
_rightGripper.DragCompleted -= new DragCompletedEventHandler(OnColumnHeaderGripperDragCompleted);
_rightGripper.MouseDoubleClick -= new MouseButtonEventHandler(OnGripperDoubleClicked);
_rightGripper = null;
}
}
///
/// Returns either this header or the one before it depending on which Gripper fired the event.
///
///
private DataGridColumnHeader HeaderToResize(object gripper)
{
return (gripper == _rightGripper) ? this : PreviousVisibleHeader;
}
// Save the original widths before header resize
private void OnColumnHeaderGripperDragStarted(object sender, DragStartedEventArgs e)
{
DataGridColumnHeader header = HeaderToResize(sender);
if (header != null)
{
if (header.Column != null)
{
DataGrid dataGrid = header.Column.DataGridOwner;
if (dataGrid != null)
{
dataGrid.InternalColumns.OnColumnResizeStarted();
}
}
e.Handled = true;
}
}
private void OnColumnHeaderResize(object sender, DragDeltaEventArgs e)
{
DataGridColumnHeader header = HeaderToResize(sender);
if (header != null)
{
RecomputeColumnWidthsOnColumnResize(header, e.HorizontalChange);
e.Handled = true;
}
}
///
/// Method which recomputes the widths of columns on resize of a header
///
private static void RecomputeColumnWidthsOnColumnResize(DataGridColumnHeader header, double horizontalChange)
{
Debug.Assert(header != null, "Header should not be null");
DataGridColumn resizingColumn = header.Column;
if (resizingColumn == null)
{
return;
}
DataGrid dataGrid = resizingColumn.DataGridOwner;
if (dataGrid == null)
{
return;
}
dataGrid.InternalColumns.RecomputeColumnWidthsOnColumnResize(resizingColumn, horizontalChange, false);
}
private void OnColumnHeaderGripperDragCompleted(object sender, DragCompletedEventArgs e)
{
DataGridColumnHeader header = HeaderToResize(sender);
if (header != null)
{
if (header.Column != null)
{
DataGrid dataGrid = header.Column.DataGridOwner;
if (dataGrid != null)
{
dataGrid.InternalColumns.OnColumnResizeCompleted(e.Canceled);
}
}
e.Handled = true;
}
}
private void OnGripperDoubleClicked(object sender, MouseButtonEventArgs e)
{
DataGridColumnHeader header = HeaderToResize(sender);
if (header != null && header.Column != null)
{
// DataGridLength is a struct, so setting to Auto resets desired and display widths to 0.0.
header.Column.Width = DataGridLength.Auto;
e.Handled = true;
}
}
private DataGridLength ColumnWidth
{
get { return Column != null ? Column.Width : DataGridLength.Auto; }
}
private double ColumnActualWidth
{
get { return Column != null ? Column.ActualWidth : ActualWidth; }
}
#endregion
#region Property Change Notification Propagation
///
/// Notifies the Header of a property change.
///
private static void OnNotifyPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((DataGridColumnHeader)d).NotifyPropertyChanged(d, e);
}
///
/// Notification for column header-related DependencyProperty changes from the grid or from columns.
///
internal void NotifyPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
DataGridColumn column = d as DataGridColumn;
if ((column != null) && (column != Column))
{
// This notification does not apply to this column header
return;
}
if (e.Property == DataGridColumn.WidthProperty)
{
DataGridHelper.OnColumnWidthChanged(this, e);
}
else if (e.Property == DataGridColumn.HeaderProperty || e.Property == ContentProperty)
{
DataGridHelper.TransferProperty(this, ContentProperty);
}
else if (e.Property == DataGridColumn.HeaderTemplateProperty || e.Property == ContentTemplateProperty)
{
DataGridHelper.TransferProperty(this, ContentTemplateProperty);
}
else if (e.Property == DataGridColumn.HeaderTemplateSelectorProperty || e.Property == ContentTemplateSelectorProperty)
{
DataGridHelper.TransferProperty(this, ContentTemplateSelectorProperty);
}
else if (e.Property == DataGridColumn.HeaderStringFormatProperty || e.Property == ContentStringFormatProperty)
{
DataGridHelper.TransferProperty(this, ContentStringFormatProperty);
}
else if (e.Property == DataGrid.ColumnHeaderStyleProperty || e.Property == DataGridColumn.HeaderStyleProperty || e.Property == StyleProperty)
{
DataGridHelper.TransferProperty(this, StyleProperty);
}
else if (e.Property == DataGrid.ColumnHeaderHeightProperty || e.Property == HeightProperty)
{
DataGridHelper.TransferProperty(this, HeightProperty);
}
else if (e.Property == DataGridColumn.DisplayIndexProperty)
{
CoerceValue(DisplayIndexProperty);
TabIndex = column.DisplayIndex;
}
else if (e.Property == DataGrid.CanUserResizeColumnsProperty)
{
OnCanUserResizeColumnsChanged();
}
else if (e.Property == DataGridColumn.CanUserSortProperty)
{
CoerceValue(CanUserSortProperty);
}
else if (e.Property == DataGridColumn.SortDirectionProperty)
{
CoerceValue(SortDirectionProperty);
}
else if (e.Property == DataGridColumn.IsFrozenProperty)
{
CoerceValue(IsFrozenProperty);
}
else if (e.Property == DataGridColumn.CanUserResizeProperty)
{
OnCanUserResizeChanged();
}
else if (e.Property == DataGridColumn.VisibilityProperty)
{
OnColumnVisibilityChanged(e);
}
}
private void OnCanUserResizeColumnsChanged()
{
Debug.Assert(Column != null, "column can't be null if we got a notification for this property change");
if (Column.DataGridOwner != null)
{
SetLeftGripperVisibility();
SetRightGripperVisibility();
}
}
private void OnCanUserResizeChanged()
{
Debug.Assert(Column != null, "column can't be null if we got a notification for this property change");
DataGrid dataGrid = Column.DataGridOwner;
if (dataGrid != null)
{
SetNextHeaderLeftGripperVisibility(Column.CanUserResize);
SetRightGripperVisibility();
}
}
private void SetLeftGripperVisibility()
{
if (_leftGripper == null || Column == null)
{
return;
}
DataGrid dataGridOwner = Column.DataGridOwner;
bool canPrevColumnResize = false;
for (int index = DisplayIndex - 1; index >= 0; index--)
{
DataGridColumn column = dataGridOwner.ColumnFromDisplayIndex(index);
if (column.IsVisible)
{
canPrevColumnResize = column.CanUserResize;
break;
}
}
SetLeftGripperVisibility(canPrevColumnResize);
}
private void SetLeftGripperVisibility(bool canPreviousColumnResize)
{
if (_leftGripper == null || Column == null)
{
return;
}
DataGrid dataGrid = Column.DataGridOwner;
if (dataGrid != null && dataGrid.CanUserResizeColumns && canPreviousColumnResize)
{
_leftGripper.Visibility = Visibility.Visible;
}
else
{
_leftGripper.Visibility = Visibility.Collapsed;
}
}
private void SetRightGripperVisibility()
{
if (_rightGripper == null || Column == null)
{
return;
}
DataGrid dataGrid = Column.DataGridOwner;
if (dataGrid != null && dataGrid.CanUserResizeColumns && Column.CanUserResize)
{
_rightGripper.Visibility = Visibility.Visible;
}
else
{
_rightGripper.Visibility = Visibility.Collapsed;
}
}
private void SetNextHeaderLeftGripperVisibility(bool canUserResize)
{
DataGrid dataGrid = Column.DataGridOwner;
int columnCount = dataGrid.Columns.Count;
for (int index = DisplayIndex + 1; index < columnCount; index++)
{
if (dataGrid.ColumnFromDisplayIndex(index).IsVisible)
{
DataGridColumnHeader nextHeader = dataGrid.ColumnHeaderFromDisplayIndex(index);
if (nextHeader != null)
{
nextHeader.SetLeftGripperVisibility(canUserResize);
}
break;
}
}
}
private void OnColumnVisibilityChanged(DependencyPropertyChangedEventArgs e)
{
Debug.Assert(Column != null, "column can't be null if we got a notification for this property change");
DataGrid dataGrid = Column.DataGridOwner;
if (dataGrid != null)
{
bool oldIsVisible = (((Visibility)e.OldValue) == Visibility.Visible);
bool newIsVisible = (((Visibility)e.NewValue) == Visibility.Visible);
if (oldIsVisible != newIsVisible)
{
if (newIsVisible)
{
SetLeftGripperVisibility();
SetRightGripperVisibility();
SetNextHeaderLeftGripperVisibility(Column.CanUserResize);
}
else
{
bool canPrevColumnResize = false;
for (int index = DisplayIndex - 1; index >= 0; index--)
{
DataGridColumn column = dataGrid.ColumnFromDisplayIndex(index);
if (column.IsVisible)
{
canPrevColumnResize = column.CanUserResize;
break;
}
}
SetNextHeaderLeftGripperVisibility(canPrevColumnResize);
}
}
}
}
#endregion
#region Style and Template Coercion callbacks
///
/// Coerces the Content property. We're choosing a value between Column.Header and the Content property on ColumnHeader.
///
private static object OnCoerceContent(DependencyObject d, object baseValue)
{
var header = d as DataGridColumnHeader;
return DataGridHelper.GetCoercedTransferPropertyValue(
header,
baseValue,
ContentProperty,
header.Column,
DataGridColumn.HeaderProperty);
}
///
/// Coerces the ContentTemplate property based on the templates defined on the Column.
///
private static object OnCoerceContentTemplate(DependencyObject d, object baseValue)
{
var columnHeader = d as DataGridColumnHeader;
return DataGridHelper.GetCoercedTransferPropertyValue(
columnHeader,
baseValue,
ContentTemplateProperty,
columnHeader.Column,
DataGridColumn.HeaderTemplateProperty);
}
///
/// Coerces the ContentTemplateSelector property based on the selector defined on the Column.
///
private static object OnCoerceContentTemplateSelector(DependencyObject d, object baseValue)
{
var columnHeader = d as DataGridColumnHeader;
return DataGridHelper.GetCoercedTransferPropertyValue(
columnHeader,
baseValue,
ContentTemplateSelectorProperty,
columnHeader.Column,
DataGridColumn.HeaderTemplateSelectorProperty);
}
///
/// Coerces the ContentStringFormat property based on the templates defined on the Column.
///
private static object OnCoerceStringFormat(DependencyObject d, object baseValue)
{
var columnHeader = d as DataGridColumnHeader;
return DataGridHelper.GetCoercedTransferPropertyValue(
columnHeader,
baseValue,
ContentStringFormatProperty,
columnHeader.Column,
DataGridColumn.HeaderStringFormatProperty);
}
///
/// Coerces the Style property based on the templates defined on the Column or DataGrid.
///
private static object OnCoerceStyle(DependencyObject d, object baseValue)
{
var columnHeader = (DataGridColumnHeader)d;
DataGridColumn column = columnHeader.Column;
DataGrid dataGrid = null;
// Propagate style changes to any filler column headers.
if (column == null)
{
DataGridColumnHeadersPresenter presenter = columnHeader.TemplatedParent as DataGridColumnHeadersPresenter;
if (presenter != null)
{
dataGrid = presenter.ParentDataGrid;
}
}
else
{
dataGrid = column.DataGridOwner;
}
return DataGridHelper.GetCoercedTransferPropertyValue(
columnHeader,
baseValue,
StyleProperty,
column,
DataGridColumn.HeaderStyleProperty,
dataGrid,
DataGrid.ColumnHeaderStyleProperty);
}
#endregion
#region Auto Sort
///
/// DependencyPropertyKey for CanUserSort property
///
private static readonly DependencyPropertyKey CanUserSortPropertyKey =
DependencyProperty.RegisterReadOnly(
"CanUserSort",
typeof(bool),
typeof(DataGridColumnHeader),
new FrameworkPropertyMetadata(true, null, new CoerceValueCallback(OnCoerceCanUserSort)));
///
/// The DependencyProperty for the CanUserSort property.
///
public static readonly DependencyProperty CanUserSortProperty = CanUserSortPropertyKey.DependencyProperty;
///
/// CanUserSort is the flag which determines if the datagrid can be sorted based on the column of this header
///
public bool CanUserSort
{
get { return (bool)GetValue(CanUserSortProperty); }
}
///
/// DependencyPropertyKey for SortDirection property
///
private static readonly DependencyPropertyKey SortDirectionPropertyKey =
DependencyProperty.RegisterReadOnly(
"SortDirection",
typeof(Nullable),
typeof(DataGridColumnHeader),
new FrameworkPropertyMetadata(null, OnVisualStatePropertyChanged, new CoerceValueCallback(OnCoerceSortDirection)));
///
/// The DependencyProperty for the SortDirection property.
///
public static readonly DependencyProperty SortDirectionProperty = SortDirectionPropertyKey.DependencyProperty;
///
/// The property for current sort direction of the column of this header
///
public Nullable SortDirection
{
get { return (Nullable)GetValue(SortDirectionProperty); }
}
///
/// The override of ButtonBase.OnClick.
/// Informs the owning datagrid to sort itself after the execution of usual button stuff
///
protected override void OnClick()
{
if (!SuppressClickEvent)
{
if (AutomationPeer.ListenerExists(AutomationEvents.InvokePatternOnInvoked))
{
AutomationPeer peer = UIElementAutomationPeer.CreatePeerForElement(this);
if (peer != null)
{
peer.RaiseAutomationEvent(AutomationEvents.InvokePatternOnInvoked);
}
}
base.OnClick();
if (Column != null &&
Column.DataGridOwner != null)
{
Column.DataGridOwner.PerformSort(Column);
}
}
}
///
/// Coercion callback for Height property.
///
private static object OnCoerceHeight(DependencyObject d, object baseValue)
{
var columnHeader = (DataGridColumnHeader)d;
DataGridColumn column = columnHeader.Column;
DataGrid dataGrid = null;
// Propagate style changes to any filler column headers.
if (column == null)
{
DataGridColumnHeadersPresenter presenter = columnHeader.TemplatedParent as DataGridColumnHeadersPresenter;
if (presenter != null)
{
dataGrid = presenter.ParentDataGrid;
}
}
else
{
dataGrid = column.DataGridOwner;
}
return DataGridHelper.GetCoercedTransferPropertyValue(
columnHeader,
baseValue,
HeightProperty,
dataGrid,
DataGrid.ColumnHeaderHeightProperty);
}
///
/// Coercion callback for CanUserSort property. Checks for the value of CanUserSort on owning column
/// and returns accordingly
///
private static object OnCoerceCanUserSort(DependencyObject d, object baseValue)
{
DataGridColumnHeader header = (DataGridColumnHeader)d;
DataGridColumn column = header.Column;
if (column != null)
{
return column.CanUserSort;
}
return baseValue;
}
///
/// Coercion callback for SortDirection property
///
private static object OnCoerceSortDirection(DependencyObject d, object baseValue)
{
DataGridColumnHeader header = (DataGridColumnHeader)d;
DataGridColumn column = header.Column;
if (column != null)
{
return column.SortDirection;
}
return baseValue;
}
#endregion
#region Automation
protected override System.Windows.Automation.Peers.AutomationPeer OnCreateAutomationPeer()
{
return new System.Windows.Automation.Peers.DataGridColumnHeaderAutomationPeer(this);
}
// Called from DataGridColumnHeaderAutomationPeer
internal void Invoke()
{
this.OnClick();
}
#endregion
#region Frozen Columns
///
/// DependencyPropertyKey for IsFrozen property
///
private static readonly DependencyPropertyKey IsFrozenPropertyKey =
DependencyProperty.RegisterReadOnly(
"IsFrozen",
typeof(bool),
typeof(DataGridColumnHeader),
new FrameworkPropertyMetadata(false, null, new CoerceValueCallback(OnCoerceIsFrozen)));
///
/// The DependencyProperty for the IsFrozen property.
///
public static readonly DependencyProperty IsFrozenProperty = IsFrozenPropertyKey.DependencyProperty;
///
/// The property to determine if the column corresponding to this header is frozen or not
///
public bool IsFrozen
{
get { return (bool)GetValue(IsFrozenProperty); }
}
///
/// Coercion callback for IsFrozen property
///
private static object OnCoerceIsFrozen(DependencyObject d, object baseValue)
{
DataGridColumnHeader header = (DataGridColumnHeader)d;
DataGridColumn column = header.Column;
if (column != null)
{
return column.IsFrozen;
}
return baseValue;
}
///
/// Coercion call back for clip property which ensures that the header overlapping with frozen
/// column gets clipped appropriately.
///
private static object OnCoerceClip(DependencyObject d, object baseValue)
{
DataGridColumnHeader header = (DataGridColumnHeader)d;
Geometry geometry = baseValue as Geometry;
Geometry frozenGeometry = DataGridHelper.GetFrozenClipForCell(header);
if (frozenGeometry != null)
{
if (geometry == null)
{
return frozenGeometry;
}
geometry = new CombinedGeometry(GeometryCombineMode.Intersect, geometry, frozenGeometry);
}
return geometry;
}
#endregion
#region Column Reordering
internal DataGridColumnHeadersPresenter ParentPresenter
{
get
{
if (_parentPresenter == null)
{
_parentPresenter = ItemsControl.ItemsControlFromItemContainer(this) as DataGridColumnHeadersPresenter;
}
return _parentPresenter;
}
}
///
/// Property which determines if click event has to raised or not. Used during column drag drop which could
/// be mis-interpreted as a click
///
internal bool SuppressClickEvent
{
get
{
return _suppressClickEvent;
}
set
{
_suppressClickEvent = value;
}
}
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
{
base.OnMouseLeftButtonDown(e);
DataGridColumnHeadersPresenter parentPresenter = ParentPresenter;
if (parentPresenter != null)
{
// If clickmode is hover then during the mouse move the hover events will be sent
// all the headers in the path. To avoid that we are using a capture
if (ClickMode == ClickMode.Hover && e.ButtonState == MouseButtonState.Pressed)
{
CaptureMouse();
}
parentPresenter.OnHeaderMouseLeftButtonDown(e);
e.Handled = true;
}
}
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
DataGridColumnHeadersPresenter parentPresenter = ParentPresenter;
if (parentPresenter != null)
{
parentPresenter.OnHeaderMouseMove(e);
e.Handled = true;
}
}
protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
{
base.OnMouseLeftButtonUp(e);
DataGridColumnHeadersPresenter parentPresenter = ParentPresenter;
if (parentPresenter != null)
{
if (ClickMode == ClickMode.Hover && IsMouseCaptured)
{
ReleaseMouseCapture();
}
parentPresenter.OnHeaderMouseLeftButtonUp(e);
e.Handled = true;
}
}
protected override void OnLostMouseCapture(MouseEventArgs e)
{
base.OnLostMouseCapture(e);
DataGridColumnHeadersPresenter parentPresenter = ParentPresenter;
if (parentPresenter != null)
{
parentPresenter.OnHeaderLostMouseCapture(e);
e.Handled = true;
}
}
///
/// Style key for DataGridColumnDropSeparator
///
public static ComponentResourceKey ColumnHeaderDropSeparatorStyleKey
{
get
{
return SystemResourceKey.DataGridColumnHeaderColumnHeaderDropSeparatorStyleKey;
}
}
///
/// Style key for DataGridColumnFloatingHeader
///
public static ComponentResourceKey ColumnFloatingHeaderStyleKey
{
get
{
return SystemResourceKey.DataGridColumnHeaderColumnFloatingHeaderStyleKey;
}
}
#endregion
#region VSM
internal override void ChangeVisualState(bool useTransitions)
{
// Common States
if (IsPressed)
{
VisualStates.GoToState(this, useTransitions, VisualStates.StatePressed, VisualStates.StateMouseOver, VisualStates.StateNormal);
}
else if (IsMouseOver)
{
VisualStates.GoToState(this, useTransitions, VisualStates.StateMouseOver, VisualStates.StateNormal);
}
else
{
VisualStateManager.GoToState(this, VisualStates.StateNormal, useTransitions);
}
// Sort States
var sortDirection = SortDirection;
if (sortDirection != null)
{
if (sortDirection == ListSortDirection.Ascending)
{
VisualStates.GoToState(this, useTransitions, VisualStates.StateSortAscending, VisualStates.StateUnsorted);
}
if (sortDirection == ListSortDirection.Descending)
{
VisualStates.GoToState(this, useTransitions, VisualStates.StateSortDescending, VisualStates.StateUnsorted);
}
}
else
{
VisualStateManager.GoToState(this, VisualStates.StateUnsorted, useTransitions);
}
// Don't call base.ChangeVisualState because we dont want to pick up the button's state changes.
// This is because SL didn't declare several of the states that Button defines, and we need to be
// compatible with them.
ChangeValidationVisualState(useTransitions);
}
#endregion
#region Helpers
DataGridColumn IProvideDataGridColumn.Column
{
get
{
return _column;
}
}
private Panel ParentPanel
{
get
{
return VisualParent as Panel;
}
}
///
/// Used by the resize code -- this is the header that the left gripper should be resizing.
///
private DataGridColumnHeader PreviousVisibleHeader
{
get
{
//
DataGridColumn column = Column;
if (column != null)
{
DataGrid dataGridOwner = column.DataGridOwner;
if (dataGridOwner != null)
{
for (int index = DisplayIndex - 1; index >= 0; index--)
{
if (dataGridOwner.ColumnFromDisplayIndex(index).IsVisible)
{
return dataGridOwner.ColumnHeaderFromDisplayIndex(index);
}
}
}
}
return null;
}
}
#endregion
#region Data
private DataGridColumn _column;
private ContainerTracking _tracker;
private DataGridColumnHeadersPresenter _parentPresenter;
private Thumb _leftGripper, _rightGripper;
private bool _suppressClickEvent;
private const string LeftHeaderGripperTemplateName = "PART_LeftHeaderGripper";
private const string RightHeaderGripperTemplateName = "PART_RightHeaderGripper";
#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
- ChtmlPhoneCallAdapter.cs
- QilStrConcat.cs
- PngBitmapEncoder.cs
- TypeDescriptionProvider.cs
- FrugalMap.cs
- SmiTypedGetterSetter.cs
- XmlSerializerAssemblyAttribute.cs
- ResourceProviderFactory.cs
- ScrollChangedEventArgs.cs
- TextRunCacheImp.cs
- StringPropertyBuilder.cs
- AnonymousIdentificationSection.cs
- NullPackagingPolicy.cs
- QilVisitor.cs
- CompositeFontInfo.cs
- Subset.cs
- XmlTextWriter.cs
- XsltCompileContext.cs
- AQNBuilder.cs
- Event.cs
- XslVisitor.cs
- StyleBamlRecordReader.cs
- BitmapImage.cs
- SpecialFolderEnumConverter.cs
- CaseStatement.cs
- LocalizableAttribute.cs
- SqlUserDefinedTypeAttribute.cs
- JoinGraph.cs
- PlacementWorkspace.cs
- TileBrush.cs
- DataPagerFieldItem.cs
- ToolStripItemDataObject.cs
- MultilineStringConverter.cs
- XmlSchemaAttributeGroupRef.cs
- AppDomainProtocolHandler.cs
- NativeMethods.cs
- ClientTargetCollection.cs
- ExpressionsCollectionConverter.cs
- FastPropertyAccessor.cs
- SiteMapDataSourceDesigner.cs
- DesignerActionUI.cs
- IdentityModelStringsVersion1.cs
- DataBoundControlAdapter.cs
- httpserverutility.cs
- DesignerDataView.cs
- ConnectionStringsExpressionBuilder.cs
- EntityStoreSchemaGenerator.cs
- MetadataItemEmitter.cs
- BitSet.cs
- ConditionCollection.cs
- ViewSimplifier.cs
- TableAutomationPeer.cs
- UmAlQuraCalendar.cs
- DateTimeOffsetConverter.cs
- CompositeControl.cs
- QilScopedVisitor.cs
- ImageDrawing.cs
- RelatedImageListAttribute.cs
- XmlnsDictionary.cs
- Timer.cs
- ActivationArguments.cs
- AssemblyContextControlItem.cs
- PersistenceContext.cs
- Group.cs
- UrlMapping.cs
- WebConfigurationManager.cs
- DataGridViewRowErrorTextNeededEventArgs.cs
- AccessedThroughPropertyAttribute.cs
- SettingsPropertyCollection.cs
- DateTimePickerDesigner.cs
- ZipIOBlockManager.cs
- _ReceiveMessageOverlappedAsyncResult.cs
- VersionUtil.cs
- TdsParameterSetter.cs
- ObjectDataSource.cs
- ChangeProcessor.cs
- ArraySegment.cs
- HttpHandlerAction.cs
- EmptyStringExpandableObjectConverter.cs
- ShaderEffect.cs
- HMACMD5.cs
- ClientUrlResolverWrapper.cs
- HMACSHA256.cs
- DefaultEvaluationContext.cs
- XmlWriter.cs
- FormattedTextSymbols.cs
- CompilationUtil.cs
- OnOperation.cs
- UIHelper.cs
- ToolStripContainer.cs
- TextStore.cs
- Underline.cs
- XmlSequenceWriter.cs
- EllipseGeometry.cs
- TypedTableBaseExtensions.cs
- UnicodeEncoding.cs
- XmlDataContract.cs
- TextEditorParagraphs.cs
- DataControlPagerLinkButton.cs
- MasterPage.cs