DataGridColumn.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Framework / System / Windows / Controls / DataGridColumn.cs / 1305600 / DataGridColumn.cs

                            //---------------------------------------------------------------------------- 
//
// Copyright (C) Microsoft Corporation.  All rights reserved.
//
//--------------------------------------------------------------------------- 

using System; 
using System.ComponentModel; 
using System.Diagnostics;
using System.Reflection; 
using System.Windows;
using System.Windows.Data;
using System.Windows.Input;
using MS.Internal; 

namespace System.Windows.Controls 
{ 
    /// 
    ///     A base class for specifying the column definitions. 
    /// 
    public abstract class DataGridColumn : DependencyObject
    {
        #region Header 

        ///  
        ///     An object that represents the header of this column. 
        /// 
        public object Header 
        {
            get { return (object)GetValue(HeaderProperty); }
            set { SetValue(HeaderProperty, value); }
        } 

        ///  
        ///     The DependencyProperty that represents the Header property. 
        /// 
        public static readonly DependencyProperty HeaderProperty = 
            DependencyProperty.Register("Header", typeof(object), typeof(DataGridColumn), new FrameworkPropertyMetadata(null, new PropertyChangedCallback(OnNotifyColumnHeaderPropertyChanged)));

        /// 
        ///     The Style for the DataGridColumnHeader 
        /// 
        public Style HeaderStyle 
        { 
            get { return (Style)GetValue(HeaderStyleProperty); }
            set { SetValue(HeaderStyleProperty, value); } 
        }

        /// 
        ///     The DependencyProperty that represents the HeaderStyle property. 
        /// 
        public static readonly DependencyProperty HeaderStyleProperty = 
            DependencyProperty.Register("HeaderStyle", typeof(Style), typeof(DataGridColumn), new FrameworkPropertyMetadata(null, OnNotifyColumnHeaderPropertyChanged, OnCoerceHeaderStyle)); 

        private static object OnCoerceHeaderStyle(DependencyObject d, object baseValue) 
        {
            var column = d as DataGridColumn;
            return DataGridHelper.GetCoercedTransferPropertyValue(
                column, 
                baseValue,
                HeaderStyleProperty, 
                column.DataGridOwner, 
                DataGrid.ColumnHeaderStyleProperty);
        } 

        /// 
        ///     The string format to apply to the header.
        ///  
        public string HeaderStringFormat
        { 
            get { return (string)GetValue(HeaderStringFormatProperty); } 
            set { SetValue(HeaderStringFormatProperty, value); }
        } 

        /// 
        ///     The DependencyProperty that represents the HeaderStringFormat property.
        ///  
        public static readonly DependencyProperty HeaderStringFormatProperty =
            DependencyProperty.Register("HeaderStringFormat", typeof(string), typeof(DataGridColumn), new FrameworkPropertyMetadata(null, OnNotifyColumnHeaderPropertyChanged)); 
 
        /// 
        ///     The template that defines the visual representation of the header. 
        /// 
        public DataTemplate HeaderTemplate
        {
            get { return (DataTemplate)GetValue(HeaderTemplateProperty); } 
            set { SetValue(HeaderTemplateProperty, value); }
        } 
 
        /// 
        ///     The DependencyProperty that represents the HeaderTemplate property. 
        /// 
        public static readonly DependencyProperty HeaderTemplateProperty =
            DependencyProperty.Register("HeaderTemplate", typeof(DataTemplate), typeof(DataGridColumn), new FrameworkPropertyMetadata(null, OnNotifyColumnHeaderPropertyChanged));
 
        /// 
        ///     DataTemplateSelector that selects which template to use for the Column Header 
        ///  
        public DataTemplateSelector HeaderTemplateSelector
        { 
            get { return (DataTemplateSelector)GetValue(HeaderTemplateSelectorProperty); }
            set { SetValue(HeaderTemplateSelectorProperty, value); }
        }
 
        /// 
        ///     The DependencyProperty that represents the HeaderTemplateSelector property. 
        ///  
        public static readonly DependencyProperty HeaderTemplateSelectorProperty =
            DependencyProperty.Register("HeaderTemplateSelector", typeof(DataTemplateSelector), typeof(DataGridColumn), new FrameworkPropertyMetadata(null, OnNotifyColumnHeaderPropertyChanged)); 

        #endregion

        #region Cell Container 

        ///  
        ///     A style to apply to the container of cells in this column. 
        /// 
        public Style CellStyle 
        {
            get { return (Style)GetValue(CellStyleProperty); }
            set { SetValue(CellStyleProperty, value); }
        } 

        ///  
        ///     The DependencyProperty that represents the CellStyle property. 
        /// 
        public static readonly DependencyProperty CellStyleProperty = 
            DependencyProperty.Register("CellStyle", typeof(Style), typeof(DataGridColumn), new FrameworkPropertyMetadata(null, OnNotifyCellPropertyChanged, OnCoerceCellStyle));

        private static object OnCoerceCellStyle(DependencyObject d, object baseValue)
        { 
            var column = d as DataGridColumn;
            return DataGridHelper.GetCoercedTransferPropertyValue( 
                column, 
                baseValue,
                CellStyleProperty, 
                column.DataGridOwner,
                DataGrid.CellStyleProperty);
        }
 
        /// 
        ///     Whether cells in this column can enter edit mode. 
        ///  
        public bool IsReadOnly
        { 
            get { return (bool)GetValue(IsReadOnlyProperty); }
            set { SetValue(IsReadOnlyProperty, value); }
        }
 
        /// 
        ///     The DependencyProperty that represents the IsReadOnly property. 
        ///  
        public static readonly DependencyProperty IsReadOnlyProperty =
            DependencyProperty.Register("IsReadOnly", typeof(bool), typeof(DataGridColumn), new FrameworkPropertyMetadata(false, OnNotifyCellPropertyChanged, OnCoerceIsReadOnly)); 

        private static object OnCoerceIsReadOnly(DependencyObject d, object baseValue)
        {
            var column = d as DataGridColumn; 
            return column.OnCoerceIsReadOnly((bool)baseValue);
        } 
 
        /// 
        ///     Subtypes can override this to force IsReadOnly to be coerced to true. 
        /// 
        protected virtual bool OnCoerceIsReadOnly(bool baseValue)
        {
            return (bool)DataGridHelper.GetCoercedTransferPropertyValue( 
                this,
                baseValue, 
                IsReadOnlyProperty, 
                DataGridOwner,
                DataGrid.IsReadOnlyProperty); 
        }

        #endregion
 
        #region Width
 
        ///  
        ///     Specifies the width of the header and cells within this column.
        ///  
        public DataGridLength Width
        {
            get { return (DataGridLength)GetValue(WidthProperty); }
            set { SetValue(WidthProperty, value); } 
        }
 
        ///  
        ///     The DependencyProperty that represents the Width property.
        ///  
        public static readonly DependencyProperty WidthProperty =
            DependencyProperty.Register(
                "Width",
                typeof(DataGridLength), 
                typeof(DataGridColumn),
                new FrameworkPropertyMetadata(DataGridLength.Auto, new PropertyChangedCallback(OnWidthPropertyChanged), new CoerceValueCallback(OnCoerceWidth))); 
 
        /// 
        /// Internal method which sets the column's width 
        /// without actual redistribution of widths among other
        /// columns
        /// 
        ///  
        internal void SetWidthInternal(DataGridLength width)
        { 
            bool originalValue = _ignoreRedistributionOnWidthChange; 
            _ignoreRedistributionOnWidthChange = true;
            try 
            {
                Width = width;
            }
            finally 
            {
                _ignoreRedistributionOnWidthChange = originalValue; 
            } 
        }
 
        /// 
        /// Property changed call back for Width property which notification propagation
        /// and does the redistribution of widths among other columns if needed
        ///  
        /// 
        ///  
        private static void OnWidthPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
        {
            DataGridColumn column = (DataGridColumn)d; 
            DataGridLength oldWidth = (DataGridLength)e.OldValue;
            DataGridLength newWidth = (DataGridLength)e.NewValue;
            DataGrid dataGrid = column.DataGridOwner;
 
            if (dataGrid != null &&
                !DoubleUtil.AreClose(oldWidth.DisplayValue, newWidth.DisplayValue)) 
            { 
                dataGrid.InternalColumns.InvalidateAverageColumnWidth();
            } 

            if (column._processingWidthChange)
            {
                column.CoerceValue(ActualWidthProperty); 
                return;
            } 
 
            column._processingWidthChange = true;
            if (oldWidth.IsStar != newWidth.IsStar) 
            {
                column.CoerceValue(MaxWidthProperty);
            }
 
            try
            { 
                if (dataGrid != null && (newWidth.IsStar ^ oldWidth.IsStar)) 
                {
                    dataGrid.InternalColumns.InvalidateHasVisibleStarColumns(); 
                }

                column.NotifyPropertyChanged(
                    d, 
                    e,
                    DataGridNotificationTarget.ColumnCollection | 
                    DataGridNotificationTarget.Columns | 
                    DataGridNotificationTarget.Cells |
                    DataGridNotificationTarget.ColumnHeaders | 
                    DataGridNotificationTarget.CellsPresenter |
                    DataGridNotificationTarget.ColumnHeadersPresenter |
                    DataGridNotificationTarget.DataGrid);
 
                if (dataGrid != null)
                { 
                    if (!column._ignoreRedistributionOnWidthChange && column.IsVisible) 
                    {
                        if (!newWidth.IsStar && !newWidth.IsAbsolute) 
                        {
                            DataGridLength changedWidth = column.Width;
                            double displayValue = DataGridHelper.CoerceToMinMax(changedWidth.DesiredValue, column.MinWidth, column.MaxWidth);
                            column.SetWidthInternal(new DataGridLength(changedWidth.Value, changedWidth.UnitType, changedWidth.DesiredValue, displayValue)); 
                        }
 
                        dataGrid.InternalColumns.RedistributeColumnWidthsOnWidthChangeOfColumn(column, (DataGridLength)e.OldValue); 
                    }
                } 
            }
            finally
            {
                column._processingWidthChange = false; 
            }
        } 
 
        /// 
        ///     Specifies the minimum width of the header and cells within this column. 
        /// 
        public double MinWidth
        {
            get { return (double)GetValue(MinWidthProperty); } 
            set { SetValue(MinWidthProperty, value); }
        } 
 
        /// 
        ///     The DependencyProperty that represents the MinWidth property. 
        /// 
        public static readonly DependencyProperty MinWidthProperty =
            DependencyProperty.Register(
                "MinWidth", 
                typeof(double),
                typeof(DataGridColumn), 
                new FrameworkPropertyMetadata(20d, new PropertyChangedCallback(OnMinWidthPropertyChanged), new CoerceValueCallback(OnCoerceMinWidth)), 
                new ValidateValueCallback(ValidateMinWidth));
 
        /// 
        /// Property changed call back for MinWidth property which notification propagation
        /// and does the redistribution of widths among other columns if needed
        ///  
        /// 
        ///  
        private static void OnMinWidthPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
        {
            DataGridColumn column = (DataGridColumn)d; 
            DataGrid dataGrid = column.DataGridOwner;

            column.NotifyPropertyChanged(d, e, DataGridNotificationTarget.Columns);
 
            if (dataGrid != null && column.IsVisible)
            { 
                dataGrid.InternalColumns.RedistributeColumnWidthsOnMinWidthChangeOfColumn(column, (double)e.OldValue); 
            }
        } 

        /// 
        ///     Specifies the maximum width of the header and cells within this column.
        ///  
        public double MaxWidth
        { 
            get { return (double)GetValue(MaxWidthProperty); } 
            set { SetValue(MaxWidthProperty, value); }
        } 

        /// 
        ///     The DependencyProperty that represents the MaxWidth property.
        ///  
        public static readonly DependencyProperty MaxWidthProperty =
            DependencyProperty.Register( 
                "MaxWidth", 
                typeof(double),
                typeof(DataGridColumn), 
                new FrameworkPropertyMetadata(double.PositiveInfinity, new PropertyChangedCallback(OnMaxWidthPropertyChanged), new CoerceValueCallback(OnCoerceMaxWidth)),
                new ValidateValueCallback(ValidateMaxWidth));

        ///  
        /// Property changed call back for MaxWidth property which notification propagation
        /// and does the redistribution of widths among other columns if needed 
        ///  
        /// 
        ///  
        private static void OnMaxWidthPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGridColumn column = (DataGridColumn)d;
            DataGrid dataGrid = column.DataGridOwner; 

            column.NotifyPropertyChanged(d, e, DataGridNotificationTarget.Columns); 
 
            if (dataGrid != null && column.IsVisible)
            { 
                dataGrid.InternalColumns.RedistributeColumnWidthsOnMaxWidthChangeOfColumn(column, (double)e.OldValue);
            }
        }
 
        /// 
        ///     Helper method which coerces the DesiredValue or DisplayValue 
        ///     of the width. 
        /// 
        private static double CoerceDesiredOrDisplayWidthValue(double widthValue, double memberValue, DataGridLengthUnitType type) 
        {
            if (DoubleUtil.IsNaN(memberValue))
            {
                if (type == DataGridLengthUnitType.Pixel) 
                {
                    memberValue = widthValue; 
                } 
                else if (type == DataGridLengthUnitType.Auto ||
                    type == DataGridLengthUnitType.SizeToCells || 
                    type == DataGridLengthUnitType.SizeToHeader)
                {
                    memberValue = 0d;
                } 
            }
            return memberValue; 
        } 

        ///  
        ///     Coerces the WidthProperty based on the DataGrid transferred property rules
        /// 
        private static object OnCoerceWidth(DependencyObject d, object baseValue)
        { 
            var column = d as DataGridColumn;
            DataGridLength width = (DataGridLength)DataGridHelper.GetCoercedTransferPropertyValue( 
                column, 
                baseValue,
                WidthProperty, 
                column.DataGridOwner,
                DataGrid.ColumnWidthProperty);

            double newDesiredValue = CoerceDesiredOrDisplayWidthValue(width.Value, width.DesiredValue, width.UnitType); 
            double newDisplayValue = CoerceDesiredOrDisplayWidthValue(width.Value, width.DisplayValue, width.UnitType);
            newDisplayValue = (DoubleUtil.IsNaN(newDisplayValue) ? newDisplayValue : DataGridHelper.CoerceToMinMax(newDisplayValue, column.MinWidth, column.MaxWidth)); 
            if (DoubleUtil.IsNaN(newDisplayValue) || DoubleUtil.AreClose(newDisplayValue, width.DisplayValue)) 
            {
                return width; 
            }

            return new DataGridLength(
                width.Value, 
                width.UnitType,
                newDesiredValue, 
                newDisplayValue); 
        }
 
        /// 
        ///     Coerces the MinWidthProperty based on the DataGrid transferred property rules
        /// 
        private static object OnCoerceMinWidth(DependencyObject d, object baseValue) 
        {
            var column = d as DataGridColumn; 
            return DataGridHelper.GetCoercedTransferPropertyValue( 
                column,
                baseValue, 
                MinWidthProperty,
                column.DataGridOwner,
                DataGrid.MinColumnWidthProperty);
        } 

        ///  
        ///     Coerces the MaxWidthProperty based on the DataGrid transferred property rules 
        /// 
        private static object OnCoerceMaxWidth(DependencyObject d, object baseValue) 
        {
            var column = d as DataGridColumn;
            double transferValue =  (double)DataGridHelper.GetCoercedTransferPropertyValue(
                column, 
                baseValue,
                MaxWidthProperty, 
                column.DataGridOwner, 
                DataGrid.MaxColumnWidthProperty);
 
            // Coerce the Max Width to 10k pixels if infinity on a star column
            if (double.IsPositiveInfinity(transferValue) &&
                column.Width.IsStar)
            { 
                return _starMaxWidth;
            } 
 
            return transferValue;
        } 

        /// 
        ///     Validates that the minimum width is an acceptable value
        ///  
        private static bool ValidateMinWidth(object v)
        { 
            double value = (double)v; 
            return !(value < 0d || DoubleUtil.IsNaN(value) || Double.IsPositiveInfinity(value));
        } 

        /// 
        ///     Validates that the maximum width is an acceptable value
        ///  
        private static bool ValidateMaxWidth(object v)
        { 
            double value = (double)v; 
            return !(value < 0d || DoubleUtil.IsNaN(value));
        } 

        /// 
        ///      This is the width that cells and headers should use in Arrange.
        ///  
        public double ActualWidth
        { 
            get { return (double)GetValue(ActualWidthProperty); } 
            private set { SetValue(ActualWidthPropertyKey, value); }
        } 

        private static readonly DependencyPropertyKey ActualWidthPropertyKey =
            DependencyProperty.RegisterReadOnly("ActualWidth", typeof(double), typeof(DataGridColumn), new FrameworkPropertyMetadata(0.0, null, new CoerceValueCallback(OnCoerceActualWidth)));
 
        public static readonly DependencyProperty ActualWidthProperty = ActualWidthPropertyKey.DependencyProperty;
 
        private static object OnCoerceActualWidth(DependencyObject d, object baseValue) 
        {
            DataGridColumn column = ((DataGridColumn)d); 
            double actualWidth = (double)baseValue;
            double minWidth = column.MinWidth;
            double maxWidth = column.MaxWidth;
 
            // If the width is an absolute pixel value, then ActualWidth should be that value
            DataGridLength width = column.Width; 
            if (width.IsAbsolute) 
            {
                actualWidth = width.DisplayValue; 
            }

            if (actualWidth < minWidth)
            { 
                actualWidth = minWidth;
            } 
            else if (actualWidth > maxWidth) 
            {
                actualWidth = maxWidth; 
            }

            return actualWidth;
        } 

        ///  
        ///     Retrieve the proper measure constraint for cells. 
        /// 
        /// Whether a header constraint or a normal cell constraint is requested. 
        /// The value to use as the width when creating a measure constraint.
        internal double GetConstraintWidth(bool isHeader)
        {
            DataGridLength width = Width; 
            if (!DoubleUtil.IsNaN(width.DisplayValue))
            { 
                return width.DisplayValue; 
            }
 
            if (width.IsAbsolute ||
                width.IsStar ||
                (width.IsSizeToCells && isHeader) ||
                (width.IsSizeToHeader && !isHeader)) 
            {
                // In these cases, the cell's desired size does not matter. 
                // Use the column's current width as the constraint. 
                return ActualWidth;
            } 
            else
            {
                // The element gets to size to content.
                return Double.PositiveInfinity; 
            }
        } 
 
        /// 
        ///     Notifies the column of a cell's desired width. 
        ///     Updates the actual width if necessary
        /// 
        /// Whether the cell is a header or not.
        /// The desired size of the cell. 
        internal void UpdateDesiredWidthForAutoColumn(bool isHeader, double pixelWidth)
        { 
            DataGridLength width = Width; 
            double minWidth = MinWidth;
            double maxWidth = MaxWidth; 
            double displayWidth = DataGridHelper.CoerceToMinMax(pixelWidth, minWidth, maxWidth);

            if (width.IsAuto ||
                (width.IsSizeToCells && !isHeader) || 
                (width.IsSizeToHeader && isHeader))
            { 
                if (DoubleUtil.IsNaN(width.DesiredValue) || 
                    DoubleUtil.LessThan(width.DesiredValue, pixelWidth))
                { 
                    if (DoubleUtil.IsNaN(width.DisplayValue))
                    {
                        SetWidthInternal(new DataGridLength(width.Value, width.UnitType, pixelWidth, displayWidth));
                    } 
                    else
                    { 
                        double originalDesiredValue = DataGridHelper.CoerceToMinMax(width.DesiredValue, minWidth, maxWidth); 
                        SetWidthInternal(new DataGridLength(width.Value, width.UnitType, pixelWidth, width.DisplayValue));
                        if (DoubleUtil.AreClose(originalDesiredValue, width.DisplayValue)) 
                        {
                            DataGridOwner.InternalColumns.RecomputeColumnWidthsOnColumnResize(this, pixelWidth - width.DisplayValue, true);
                        }
                    } 

                    width = Width; 
                } 

                if (DoubleUtil.IsNaN(width.DisplayValue)) 
                {
                    if (ActualWidth < displayWidth)
                    {
                        ActualWidth = displayWidth; 
                    }
                } 
                else if (!DoubleUtil.AreClose(ActualWidth, width.DisplayValue)) 
                {
                    ActualWidth = width.DisplayValue; 
                }
            }
        }
 
        /// 
        ///     Notifies the column that Width="*" columns have a new actual width. 
        ///  
        internal void UpdateWidthForStarColumn(double displayWidth, double desiredWidth, double starValue)
        { 
            Debug.Assert(Width.IsStar);
            DataGridLength width = Width;

            if (!DoubleUtil.AreClose(displayWidth, width.DisplayValue) || 
                !DoubleUtil.AreClose(desiredWidth, width.DesiredValue) ||
                !DoubleUtil.AreClose(width.Value, starValue)) 
            { 
                SetWidthInternal(new DataGridLength(starValue, width.UnitType, desiredWidth, displayWidth));
                ActualWidth = displayWidth; 
            }
        }

        #endregion 

        #region Visual Tree Generation 
 
        /// 
        ///     Retrieves the visual tree that was generated for a particular row and column. 
        /// 
        /// The row that corresponds to the desired cell.
        /// The element if found, null otherwise.
        public FrameworkElement GetCellContent(object dataItem) 
        {
            if (dataItem == null) 
            { 
                throw new ArgumentNullException("dataItem");
            } 

            if (_dataGridOwner != null)
            {
                DataGridRow row = _dataGridOwner.ItemContainerGenerator.ContainerFromItem(dataItem) as DataGridRow; 
                if (row != null)
                { 
                    return GetCellContent(row); 
                }
            } 

            return null;
        }
 
        /// 
        ///     Retrieves the visual tree that was generated for a particular row and column. 
        ///  
        /// The row that corresponds to the desired cell.
        /// The element if found, null otherwise. 
        public FrameworkElement GetCellContent(DataGridRow dataGridRow)
        {
            if (dataGridRow == null)
            { 
                throw new ArgumentNullException("dataGridRow");
            } 
 
            if (_dataGridOwner != null)
            { 
                int columnIndex = _dataGridOwner.Columns.IndexOf(this);
                if (columnIndex >= 0)
                {
                    DataGridCell cell = dataGridRow.TryGetCell(columnIndex); 
                    if (cell != null)
                    { 
                        return cell.Content as FrameworkElement; 
                    }
                } 
            }

            return null;
        } 

        ///  
        ///     Creates the visual tree that will become the content of a cell. 
        /// 
        /// Whether the editing version is being requested. 
        /// The data item for the cell.
        /// The cell container that will receive the tree.
        internal FrameworkElement BuildVisualTree(bool isEditing, object dataItem, DataGridCell cell)
        { 
            if (isEditing)
            { 
                return GenerateEditingElement(cell, dataItem); 
            }
            else 
            {
                return GenerateElement(cell, dataItem);
            }
        } 

        ///  
        ///     Creates the visual tree that will become the content of a cell. 
        /// 
        protected abstract FrameworkElement GenerateElement(DataGridCell cell, object dataItem); 

        /// 
        ///     Creates the visual tree that will become the content of a cell.
        ///  
        protected abstract FrameworkElement GenerateEditingElement(DataGridCell cell, object dataItem);
 
        #endregion 

        #region Editing 

        /// 
        ///     Called when a cell has just switched to edit mode.
        ///  
        /// A reference to element returned by GenerateEditingElement.
        /// The unedited value of the cell. 
        protected virtual object PrepareCellForEdit(FrameworkElement editingElement, RoutedEventArgs editingEventArgs) 
        {
            return null; 
        }

        /// 
        ///     Called when a cell's value is to be restored to its original value, 
        ///     just before it exits edit mode.
        ///  
        /// A reference to element returned by GenerateEditingElement. 
        /// The original, unedited value of the cell.
        protected virtual void CancelCellEdit(FrameworkElement editingElement, object uneditedValue) 
        {
            DataGridHelper.UpdateTarget(editingElement);
        }
 
        /// 
        ///     Called when a cell's value is to be committed, just before it exits edit mode. 
        ///  
        /// A reference to element returned by GenerateEditingElement.
        /// false if there is a validation error. true otherwise. 
        protected virtual bool CommitCellEdit(FrameworkElement editingElement)
        {
            return DataGridHelper.ValidateWithoutUpdate(editingElement);
        } 

        internal void BeginEdit(FrameworkElement editingElement, RoutedEventArgs e) 
        { 
            // This call is to ensure that the tree and its bindings have resolved
            // before we proceed to code that relies on the tree being ready. 
            if (editingElement != null)
            {
                editingElement.UpdateLayout();
 
                object originalValue = PrepareCellForEdit(editingElement, e);
                SetOriginalValue(editingElement, originalValue); 
            } 
        }
 
        internal void CancelEdit(FrameworkElement editingElement)
        {
            if (editingElement != null)
            { 
                CancelCellEdit(editingElement, GetOriginalValue(editingElement));
                ClearOriginalValue(editingElement); 
            } 
        }
 
        internal bool CommitEdit(FrameworkElement editingElement)
        {
            if (editingElement != null)
            { 
                if (CommitCellEdit(editingElement))
                { 
                    // Validation passed 
                    ClearOriginalValue(editingElement);
                    return true; 
                }
                else
                {
                    // Validation failed. This cell will remain in edit mode. 
                    return false;
                } 
            } 

            return true; 
        }

        private static object GetOriginalValue(DependencyObject obj)
        { 
            return (object)obj.GetValue(OriginalValueProperty);
        } 
 
        private static void SetOriginalValue(DependencyObject obj, object value)
        { 
            obj.SetValue(OriginalValueProperty, value);
        }

        private static void ClearOriginalValue(DependencyObject obj) 
        {
            obj.ClearValue(OriginalValueProperty); 
        } 

        private static readonly DependencyProperty OriginalValueProperty = 
            DependencyProperty.RegisterAttached("OriginalValue", typeof(object), typeof(DataGridColumn), new FrameworkPropertyMetadata(null));

        #endregion
 
        #region Owner Communication
 
        ///  
        ///     Notifies the DataGrid and the Cells about property changes.
        ///  
        internal static void OnNotifyCellPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((DataGridColumn)d).NotifyPropertyChanged(d, e, DataGridNotificationTarget.Columns | DataGridNotificationTarget.Cells);
        } 

        ///  
        ///     Notifies the DataGrid and the Column Headers about property changes. 
        /// 
        private static void OnNotifyColumnHeaderPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
        {
            ((DataGridColumn)d).NotifyPropertyChanged(d, e, DataGridNotificationTarget.Columns | DataGridNotificationTarget.ColumnHeaders);
        }
 
        /// 
        ///     Notifies parts that respond to changes in the column. 
        ///  
        private static void OnNotifyColumnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        { 
            ((DataGridColumn)d).NotifyPropertyChanged(d, e, DataGridNotificationTarget.Columns);
        }

        ///  
        ///   General notification for DependencyProperty changes from the grid and/or column.
        ///  
        internal void NotifyPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e, DataGridNotificationTarget target) 
        {
            if (DataGridHelper.ShouldNotifyColumns(target)) 
            {
                // Remove columns target since we're handling it.  If we're targeting multiple targets it may also need to get
                // sent to the DataGrid.
                target &= ~DataGridNotificationTarget.Columns; 

                if (e.Property == DataGrid.MaxColumnWidthProperty || e.Property == MaxWidthProperty) 
                { 
                    DataGridHelper.TransferProperty(this, MaxWidthProperty);
                } 
                else if (e.Property == DataGrid.MinColumnWidthProperty || e.Property == MinWidthProperty)
                {
                    DataGridHelper.TransferProperty(this, MinWidthProperty);
                } 
                else if (e.Property == DataGrid.ColumnWidthProperty || e.Property == WidthProperty)
                { 
                    DataGridHelper.TransferProperty(this, WidthProperty); 
                }
                else if (e.Property == DataGrid.ColumnHeaderStyleProperty || e.Property == HeaderStyleProperty) 
                {
                    DataGridHelper.TransferProperty(this, HeaderStyleProperty);
                }
                else if (e.Property == DataGrid.CellStyleProperty || e.Property == CellStyleProperty) 
                {
                    DataGridHelper.TransferProperty(this, CellStyleProperty); 
                } 
                else if (e.Property == DataGrid.IsReadOnlyProperty || e.Property == IsReadOnlyProperty)
                { 
                    DataGridHelper.TransferProperty(this, IsReadOnlyProperty);
                }
                else if (e.Property == DataGrid.DragIndicatorStyleProperty || e.Property == DragIndicatorStyleProperty)
                { 
                    DataGridHelper.TransferProperty(this, DragIndicatorStyleProperty);
                } 
                else if (e.Property == DisplayIndexProperty) 
                {
                    CoerceValue(IsFrozenProperty); 
                }
                else if (e.Property == DataGrid.CanUserSortColumnsProperty)
                {
                    DataGridHelper.TransferProperty(this, CanUserSortProperty); 
                }
                else if (e.Property == DataGrid.CanUserResizeColumnsProperty || e.Property == CanUserResizeProperty) 
                { 
                    DataGridHelper.TransferProperty(this, CanUserResizeProperty);
                } 
                else if (e.Property == DataGrid.CanUserReorderColumnsProperty || e.Property == CanUserReorderProperty)
                {
                    DataGridHelper.TransferProperty(this, CanUserReorderProperty);
                } 

                if (e.Property == WidthProperty || e.Property == MinWidthProperty || e.Property == MaxWidthProperty) 
                { 
                    CoerceValue(ActualWidthProperty);
                } 
            }

            if (target != DataGridNotificationTarget.None)
            { 
                // Everything else gets sent to the DataGrid so it can propogate back down
                // to the targets that need notification. 
                DataGridColumn column = (DataGridColumn)d; 
                DataGrid dataGridOwner = column.DataGridOwner;
                if (dataGridOwner != null) 
                {
                    dataGridOwner.NotifyPropertyChanged(d, e, target);
                }
            } 
        }
 
        ///  
        /// Method which propogates the property changed notification to datagrid
        ///  
        /// 
        protected void NotifyPropertyChanged(string propertyName)
        {
            if (DataGridOwner != null) 
            {
                DataGridOwner.NotifyPropertyChanged(this, propertyName, new DependencyPropertyChangedEventArgs(), DataGridNotificationTarget.RefreshCellContent); 
            } 
        }
 
        /// 
        /// Method used as property changed callback for properties which need RefreshCellContent to be called
        /// 
        ///  
        /// 
        internal static void NotifyPropertyChangeForRefreshContent(DependencyObject d, DependencyPropertyChangedEventArgs e) 
        { 
            Debug.Assert(d is DataGridColumn, "d should be a DataGridColumn");
 
            ((DataGridColumn)d).NotifyPropertyChanged(e.Property.Name);
        }

        ///  
        /// Method which updates the cell for property changes
        ///  
        ///  
        /// 
        protected internal virtual void RefreshCellContent(FrameworkElement element, string propertyName) 
        {
        }

        ///  
        ///     Ensures that any properties that may be influenced by a change to the DataGrid are syncronized.
        ///  
        internal void SyncProperties() 
        {
            DataGridHelper.TransferProperty(this, MinWidthProperty); 
            DataGridHelper.TransferProperty(this, MaxWidthProperty);
            DataGridHelper.TransferProperty(this, WidthProperty);
            DataGridHelper.TransferProperty(this, HeaderStyleProperty);
            DataGridHelper.TransferProperty(this, CellStyleProperty); 
            DataGridHelper.TransferProperty(this, IsReadOnlyProperty);
            DataGridHelper.TransferProperty(this, DragIndicatorStyleProperty); 
            DataGridHelper.TransferProperty(this, CanUserSortProperty); 
            DataGridHelper.TransferProperty(this, CanUserReorderProperty);
            DataGridHelper.TransferProperty(this, CanUserResizeProperty); 
        }

        /// 
        ///     The owning DataGrid control. 
        /// 
        protected internal DataGrid DataGridOwner 
        { 
            get { return _dataGridOwner; }
            internal set { _dataGridOwner = value; } 
        }

        #endregion
 
        #region Display Index
 
        ///  
        ///     Specifies the display index of this column.
        ///  
        /// 
        ///     A lower display index means a column will appear first (to the left) of columns with a higher display index.
        ///     Allowable values are from 0 to num columns - 1. (-1 is legal only as the default value and is modified to something else
        ///     when the column is added to a DataGrid's column collection). DataGrid enforces that no two columns have the same display index; 
        ///     changing the display index of a column will cause the index of other columns to adjust as well.
        ///  
        public int DisplayIndex 
        {
            get { return (int)GetValue(DisplayIndexProperty); } 
            set { SetValue(DisplayIndexProperty, value); }
        }

        ///  
        ///     The DependencyProperty that represents the Width property.
        ///  
        public static readonly DependencyProperty DisplayIndexProperty = 
            DependencyProperty.Register(
                "DisplayIndex", 
                typeof(int),
                typeof(DataGridColumn),
                new FrameworkPropertyMetadata(-1, new PropertyChangedCallback(DisplayIndexChanged), new CoerceValueCallback(OnCoerceDisplayIndex)));
 
        /// 
        ///     We use the coersion callback to validate that the DisplayIndex of a column is between 0 and DataGrid.Columns.Count 
        ///     The default value is -1; this value is only legal as the default or when the Column is not attached to a DataGrid. 
        /// 
        private static object OnCoerceDisplayIndex(DependencyObject d, object baseValue) 
        {
            DataGridColumn column = (DataGridColumn)d;

            if (column.DataGridOwner != null) 
            {
                column.DataGridOwner.ValidateDisplayIndex(column, (int)baseValue); 
            } 

            return baseValue; 
        }

        /// 
        ///     Notifies the DataGrid that the display index for this column changed. 
        /// 
        private static void DisplayIndexChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
        { 
            // Cells and ColumnHeaders invalidate Arrange; ColumnCollection handles modifying the DisplayIndex of other columns.
            ((DataGridColumn)d).NotifyPropertyChanged( 
                d,
                e,
                DataGridNotificationTarget.DataGrid |
                DataGridNotificationTarget.Columns | 
                DataGridNotificationTarget.ColumnCollection |
                DataGridNotificationTarget.Cells | 
                DataGridNotificationTarget.ColumnHeaders | 
                DataGridNotificationTarget.CellsPresenter |
                DataGridNotificationTarget.ColumnHeadersPresenter); 
        }

        #endregion
 
        #region Auto Sorting
 
        ///  
        /// Dependency property for SortMemberPath
        ///  
        public static readonly DependencyProperty SortMemberPathProperty =
            DependencyProperty.Register(
                "SortMemberPath",
                typeof(string), 
                typeof(DataGridColumn),
                new FrameworkPropertyMetadata(String.Empty)); 
 
        /// 
        /// The property which the determines the member to be sorted upon when sorted on this column 
        /// 
        public string SortMemberPath
        {
            get { return (string)GetValue(SortMemberPathProperty); } 
            set { SetValue(SortMemberPathProperty, value); }
        } 
 
        /// 
        /// Dependecy property for CanUserSort 
        /// 
        public static readonly DependencyProperty CanUserSortProperty =
            DependencyProperty.Register(
                "CanUserSort", 
                typeof(bool),
                typeof(DataGridColumn), 
                new FrameworkPropertyMetadata(true, new PropertyChangedCallback(OnCanUserSortPropertyChanged), new CoerceValueCallback(OnCoerceCanUserSort))); 

        ///  
        /// The property which determines whether the datagrid can be sorted upon this column or not
        /// 
        public bool CanUserSort
        { 
            get { return (bool)GetValue(CanUserSortProperty); }
            set { SetValue(CanUserSortProperty, value); } 
        } 

        ///  
        /// The Coercion callback for CanUserSort property. Checks if datagrid.Items can sort and
        /// returns the value accordingly.
        /// 
        ///  
        /// 
        ///  
        internal static object OnCoerceCanUserSort(DependencyObject d, object baseValue) 
        {
            var column = d as DataGridColumn; 

            bool basePropertyHasModifiers;
            BaseValueSourceInternal baseValueSource = column.GetValueSource(CanUserSortProperty, /*metadata*/ null, out basePropertyHasModifiers);
 
            if (column.DataGridOwner != null)
            { 
                bool parentPropertyHasModifiers; 
                BaseValueSourceInternal parentValueSource = column.DataGridOwner.GetValueSource(DataGrid.CanUserSortColumnsProperty, /*metadata*/ null, out parentPropertyHasModifiers);
                if (parentValueSource == baseValueSource && !basePropertyHasModifiers && parentPropertyHasModifiers) 
                {
                    return column.DataGridOwner.GetValue(DataGrid.CanUserSortColumnsProperty);
                }
            } 

            return DataGridHelper.GetCoercedTransferPropertyValue( 
                column, 
                baseValue,
                CanUserSortProperty, 
                column.DataGridOwner,
                DataGrid.CanUserSortColumnsProperty);
        }
 
        /// 
        /// Property changed callback for CanUserSort property 
        ///  
        /// 
        ///  
        private static void OnCanUserSortPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            // To prevent re-entrancy
            if (!DataGridHelper.IsPropertyTransferEnabled(d, CanUserSortProperty)) 
            {
                // Coerce value from parent DataGrid 
                DataGridHelper.TransferProperty(d, CanUserSortProperty); 
            }
            ((DataGridColumn)d).NotifyPropertyChanged(d, e, DataGridNotificationTarget.ColumnHeaders); 
        }


        ///  
        /// Dependency property for SortDirection
        ///  
        public static readonly DependencyProperty SortDirectionProperty = 
            DependencyProperty.Register(
                "SortDirection", 
                typeof(Nullable),
                typeof(DataGridColumn),
                new FrameworkPropertyMetadata(null, new PropertyChangedCallback(OnNotifySortPropertyChanged)));
 
        /// 
        /// The property for current sort direction of the column 
        ///  
        public Nullable SortDirection
        { 
            get { return (Nullable)GetValue(SortDirectionProperty); }
            set { SetValue(SortDirectionProperty, value); }
        }
 
        /// 
        /// Property changed callback for SortMemberPath and SortDirection properties 
        ///  
        /// 
        ///  
        private static void OnNotifySortPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((DataGridColumn)d).NotifyPropertyChanged(d, e, DataGridNotificationTarget.ColumnHeaders);
        } 

        #endregion 
 
        #region Auto Generation
 
        private static readonly DependencyPropertyKey IsAutoGeneratedPropertyKey =
            DependencyProperty.RegisterReadOnly(
                "IsAutoGenerated",
                typeof(bool), 
                typeof(DataGridColumn),
                new FrameworkPropertyMetadata(false)); 
 
        /// 
        /// The DependencyProperty for the IsAutoGenerated Property 
        /// 
        public static readonly DependencyProperty IsAutoGeneratedProperty = IsAutoGeneratedPropertyKey.DependencyProperty;

        ///  
        /// This property determines whether the column is autogenerate or not.
        ///  
        public bool IsAutoGenerated 
        {
            get { return (bool)GetValue(IsAutoGeneratedProperty); } 
            internal set { SetValue(IsAutoGeneratedPropertyKey, value); }
        }

        ///  
        /// Helper Method which creates a default DataGridColumn object for the specified property type.
        ///  
        ///  
        /// 
        internal static DataGridColumn CreateDefaultColumn(ItemPropertyInfo itemProperty) 
        {
            Debug.Assert(itemProperty != null && itemProperty.PropertyType != null, "itemProperty and/or its PropertyType member cannot be null");

            DataGridColumn dataGridColumn = null; 
            DataGridComboBoxColumn comboBoxColumn = null;
            Type propertyType = itemProperty.PropertyType; 
 
            // determine the type of column to be created and create one
            if (propertyType.IsEnum) 
            {
                comboBoxColumn = new DataGridComboBoxColumn();
                comboBoxColumn.ItemsSource = Enum.GetValues(propertyType);
                dataGridColumn = comboBoxColumn; 
            }
            else if (typeof(string).IsAssignableFrom(propertyType)) 
            { 
                dataGridColumn = new DataGridTextColumn();
            } 
            else if (typeof(bool).IsAssignableFrom(propertyType))
            {
                dataGridColumn = new DataGridCheckBoxColumn();
            } 
            else if (typeof(Uri).IsAssignableFrom(propertyType))
            { 
                dataGridColumn = new DataGridHyperlinkColumn(); 
            }
            else 
            {
                dataGridColumn = new DataGridTextColumn();
            }
 
            // determine if the datagrid can sort on the column or not
            if (!typeof(IComparable).IsAssignableFrom(propertyType)) 
            { 
                dataGridColumn.CanUserSort = false;
            } 

            dataGridColumn.Header = itemProperty.Name;

            // Set the data field binding for such created columns and 
            // choose the BindingMode based on editability of the property.
            DataGridBoundColumn boundColumn = dataGridColumn as DataGridBoundColumn; 
            if (boundColumn != null || comboBoxColumn != null) 
            {
                Binding binding = new Binding(itemProperty.Name); 
                if (comboBoxColumn != null)
                {
                    comboBoxColumn.SelectedItemBinding = binding;
                } 
                else
                { 
                    boundColumn.Binding = binding; 
                }
 
                PropertyDescriptor pd = itemProperty.Descriptor as PropertyDescriptor;
                if (pd != null)
                {
                    if (pd.IsReadOnly) 
                    {
                        binding.Mode = BindingMode.OneWay; 
                        dataGridColumn.IsReadOnly = true; 
                    }
                } 
                else
                {
                    PropertyInfo pi = itemProperty.Descriptor as PropertyInfo;
                    if (pi != null) 
                    {
                        if (!pi.CanWrite) 
                        { 
                            binding.Mode = BindingMode.OneWay;
                            dataGridColumn.IsReadOnly = true; 
                        }
                    }
                }
            } 

            return dataGridColumn; 
        } 

        #endregion 

        #region Frozen Columns

        ///  
        /// Dependency Property Key for IsFrozen property
        ///  
        private static readonly DependencyPropertyKey IsFrozenPropertyKey = 
            DependencyProperty.RegisterReadOnly(
                "IsFrozen", 
                typeof(bool),
                typeof(DataGridColumn),
                new FrameworkPropertyMetadata(false, new PropertyChangedCallback(OnNotifyFrozenPropertyChanged), new CoerceValueCallback(OnCoerceIsFrozen)));
 
        /// 
        /// The DependencyProperty for the IsFrozen Property 
        ///  
        public static readonly DependencyProperty IsFrozenProperty = IsFrozenPropertyKey.DependencyProperty;
 
        /// 
        /// This property determines whether the column is frozen or not.
        /// 
        public bool IsFrozen 
        {
            get { return (bool)GetValue(IsFrozenProperty); } 
            internal set { SetValue(IsFrozenPropertyKey, value); } 
        }
 
        /// 
        /// Property changed callback for IsFrozen property
        /// 
        ///  
        /// 
        private static void OnNotifyFrozenPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
        { 
            ((DataGridColumn)d).NotifyPropertyChanged(d, e, DataGridNotificationTarget.ColumnHeaders);
        } 

        /// 
        /// Coercion call back for IsFrozenProperty. Ensures that IsFrozen is set as per the
        /// DataGrid's FrozenColumnCount property. 
        /// 
        ///  
        ///  
        /// 
        private static object OnCoerceIsFrozen(DependencyObject d, object baseValue) 
        {
            DataGridColumn column = (DataGridColumn)d;
            DataGrid dataGrid = column.DataGridOwner;
            if (dataGrid != null) 
            {
                if (column.DisplayIndex < dataGrid.FrozenColumnCount) 
                { 
                    return true;
                } 
                else
                {
                    return false;
                } 
            }
 
            return baseValue; 
        }
 
        #endregion

        #region Column Reordering
 
        /// 
        ///     The DependencyProperty that represents the CanUserReorder property. 
        ///  
        public static readonly DependencyProperty CanUserReorderProperty =
            DependencyProperty.Register("CanUserReorder", typeof(bool), typeof(DataGridColumn), new FrameworkPropertyMetadata(true, new PropertyChangedCallback(OnNotifyColumnPropertyChanged), new CoerceValueCallback(OnCoerceCanUserReorder))); 

        /// 
        /// The property which determines if column header can be dragged or not
        ///  
        public bool CanUserReorder
        { 
            get { return (bool)GetValue(CanUserReorderProperty); } 
            set { SetValue(CanUserReorderProperty, value); }
        } 

        private static object OnCoerceCanUserReorder(DependencyObject d, object baseValue)
        {
            var column = d as DataGridColumn; 
            return DataGridHelper.GetCoercedTransferPropertyValue(
                column, 
                baseValue, 
                CanUserReorderProperty,
                column.DataGridOwner, 
                DataGrid.CanUserReorderColumnsProperty);
        }

        ///  
        ///     The DependencyProperty that represents the DragIndicatorStyle property.
        ///  
        public static readonly DependencyProperty DragIndicatorStyleProperty = 
            DependencyProperty.Register("DragIndicatorStyle", typeof(Style), typeof(DataGridColumn), new FrameworkPropertyMetadata(null, OnNotifyColumnPropertyChanged, OnCoerceDragIndicatorStyle));
 
        /// 
        /// The style property which would be applied on the column header drag indicator.
        /// 
        public Style DragIndicatorStyle 
        {
            get { return (Style)GetValue(DragIndicatorStyleProperty); } 
            set { SetValue(DragIndicatorStyleProperty, value); } 
        }
 
        private static object OnCoerceDragIndicatorStyle(DependencyObject d, object baseValue)
        {
            var column = d as DataGridColumn;
            return DataGridHelper.GetCoercedTransferPropertyValue( 
                column,
                baseValue, 
                DragIndicatorStyleProperty, 
                column.DataGridOwner,
                DataGrid.DragIndicatorStyleProperty); 
        }

        #endregion
 
        #region Clipboard Copy/Paste
 
        ///  
        ///     The binding that will be used to get or set cell content for the clipboard
        ///  
        public virtual BindingBase ClipboardContentBinding
        {
            get
            { 
                return _clipboardContentBinding;
            } 
 
            set
            { 
                _clipboardContentBinding = value;
            }
        }
 
        /// 
        /// This method is called for each selected cell in each selected cell to retrieve the default cell content. 
        /// Default cell content is calculated using ClipboardContentBinding. 
        /// 
        ///  
        /// 
        public virtual object OnCopyingCellClipboardContent(object item)
        {
            object cellValue = DataGridOwner.GetCellClipboardValue(item, this); 

            // Raise the event to give a chance for external listeners to modify the cell content 
            if (CopyingCellClipboardContent != null) 
            {
                DataGridCellClipboardEventArgs args = new DataGridCellClipboardEventArgs(item, this, cellValue); 
                CopyingCellClipboardContent(this, args);
                cellValue = args.Content;
            }
 
            return cellValue;
        } 
 
        /// We don't provide default Paste but this public method is exposed to help custom implementation of Paste
        ///  
        /// This method stores the cellContent into the item object using ClipboardContentBinding.
        /// 
        /// 
        ///  
        public virtual void OnPastingCellClipboardContent(object item, object cellContent)
        { 
            BindingBase binding = ClipboardContentBinding; 
            if (binding != null)
            { 
                // Raise the event to give a chance for external listeners to modify the cell content
                // before it gets stored into the cell
                if (PastingCellClipboardContent != null)
                { 
                    DataGridCellClipboardEventArgs args = new DataGridCellClipboardEventArgs(item, this, cellContent);
                    PastingCellClipboardContent(this, args); 
                    cellContent = args.Content; 
                }
 
                // Event handlers can cancel Paste of a cell by setting its content to null
                if (cellContent != null)
                {
                    DataGridOwner.SetCellClipboardValue(item, this, cellContent); 
                }
            } 
        } 

        ///  
        /// The event is raised for each selected cell after the cell clipboard content is prepared.
        /// Event handlers can modify the cell content before it gets stored into the clipboard.
        /// 
        public event EventHandler CopyingCellClipboardContent; 

        ///  
        /// The event is raised for each selected cell before the clipboard content is transfered to the cell. 
        /// Event handlers can modify the clipboard content before it gets stored into the cell content.
        ///  
        public event EventHandler PastingCellClipboardContent;

        #endregion
 
        #region Special Input
 
        // 

        internal virtual void OnInput(InputEventArgs e) 
        {
        }

        internal void BeginEdit(InputEventArgs e) 
        {
            var owner = DataGridOwner; 
            if (owner != null) 
            {
                if (owner.BeginEdit(e)) 
                {
                    e.Handled = true;
                }
            } 
        }
 
        #endregion 

        #region Column Resizing 

        /// 
        /// Dependency property for CanUserResize
        ///  
        public static readonly DependencyProperty CanUserResizeProperty =
            DependencyProperty.Register("CanUserResize", typeof(bool), typeof(DataGridColumn), new FrameworkPropertyMetadata(true, new PropertyChangedCallback(OnNotifyColumnHeaderPropertyChanged), new CoerceValueCallback(OnCoerceCanUserResize))); 
 
        /// 
        /// Property which indicates if an end user can resize the column or not 
        /// 
        public bool CanUserResize
        {
            get { return (bool)GetValue(CanUserResizeProperty); } 
            set { SetValue(CanUserResizeProperty, value); }
        } 
 
        private static object OnCoerceCanUserResize(DependencyObject d, object baseValue)
        { 
            var column = d as DataGridColumn;
            return DataGridHelper.GetCoercedTransferPropertyValue(
                column,
                baseValue, 
                CanUserResizeProperty,
                column.DataGridOwner, 
                DataGrid.CanUserResizeColumnsProperty); 
        }
 
        #endregion

        #region Hidden Columns
 
        /// 
        ///     Dependency property for Visibility 
        ///  
        public static readonly DependencyProperty VisibilityProperty =
            DependencyProperty.Register( 
                "Visibility",
                typeof(Visibility),
                typeof(DataGridColumn),
                new FrameworkPropertyMetadata(Visibility.Visible, new PropertyChangedCallback(OnVisibilityPropertyChanged))); 

        ///  
        ///     The property which determines if the column is visible or not. 
        /// 
        public Visibility Visibility 
        {
            get { return (Visibility)GetValue(VisibilityProperty); }
            set { SetValue(VisibilityProperty, value); }
        } 

        ///  
        ///     Property changed callback for Visibility property 
        /// 
        private static void OnVisibilityPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs eventArgs) 
        {
            Visibility oldVisibility = (Visibility)eventArgs.OldValue;
            Visibility newVisibility = (Visibility)eventArgs.NewValue;
 
            if (oldVisibility != Visibility.Visible && newVisibility != Visibility.Visible)
            { 
                return; 
            }
 
            ((DataGridColumn)d).NotifyPropertyChanged(
                d,
                eventArgs,
                DataGridNotificationTarget.CellsPresenter | DataGridNotificationTarget.ColumnHeadersPresenter | DataGridNotificationTarget.ColumnCollection | DataGridNotificationTarget.DataGrid | DataGridNotificationTarget.ColumnHeaders); 
        }
 
        ///  
        ///     Helper IsVisible property
        ///  
        internal bool IsVisible
        {
            get
            { 
                return Visibility == Visibility.Visible;
            } 
        } 

        #endregion 

        #region Data

        private DataGrid _dataGridOwner = null;                     // This property is updated by DataGrid when the column is added to the DataGrid.Columns collection 
        private BindingBase _clipboardContentBinding;               // Storage for ClipboardContentBinding
        private bool _ignoreRedistributionOnWidthChange = false;    // Flag which indicates to ignore recomputation of column widths on width change of column 
        private bool _processingWidthChange = false;                // Flag which indicates that execution of width change callback to avoid recursions. 
        private const double _starMaxWidth = 10000d;                // Max Width constant for star columns
 
        #endregion
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK