internal override void OnColumnCollectionChanged(GridViewColumnCollectionChangedEventArgs e)
        {
            base.OnColumnCollectionChanged(e);

            int index;
            GridViewColumnHeader header;
            UIElementCollection children = InternalChildren;
            GridViewColumn column;

            switch (e.Action)
            {
                case NotifyCollectionChangedAction.Move:
                    int start = GetVisualIndex(e.OldStartingIndex);
                    int end = GetVisualIndex(e.NewStartingIndex);

                    header = (GridViewColumnHeader)children[start];
                    children.RemoveAt(start);
                    children.InsertInternal(end, header);

                    break;

                case NotifyCollectionChangedAction.Add:
                    index = GetVisualIndex(e.NewStartingIndex);
                    column = (GridViewColumn)(e.NewItems[0]);

                    CreateAndInsertHeader(column, index + 1); // index + 1 because visual index is reversed from column index

                    break;

                case NotifyCollectionChangedAction.Remove:
                    RemoveHeader(null, GetVisualIndex(e.OldStartingIndex));

                    break;

                case NotifyCollectionChangedAction.Replace:
                    index = GetVisualIndex(e.OldStartingIndex);
                    RemoveHeader(null, index);

                    column = (GridViewColumn)(e.NewItems[0]);
                    CreateAndInsertHeader(column, index);

                    break;

                case NotifyCollectionChangedAction.Reset:
                    int count = e.ClearedColumns.Count;
                    for (int i = 0; i < count; i++)
                    {
                        RemoveHeader(null, 1);
                    }

                    break;
            }

            // Link headers
            BuildHeaderLinks();
            _isColumnChangedOrCreated = true;
        }
        /// <summary>
        /// process GridViewColumnCollection.CollectionChanged event.
        /// </summary> 
        internal override void OnColumnCollectionChanged(GridViewColumnCollectionChangedEventArgs e)
        { 
            base.OnColumnCollectionChanged(e); 

            if (e.Action == NotifyCollectionChangedAction.Move) 
            {
                InvalidateArrange();
            }
            else 
            {
                switch (e.Action) 
                { 
                    case NotifyCollectionChangedAction.Add:
                        // New child will always be appended to the very last, no matter it 
                        // is actually add via 'Insert' or just 'Add'.
                        InternalChildren.AddInternal(CreateCell((GridViewColumn)(e.NewItems[0])));
                        break;
 
                    case NotifyCollectionChangedAction.Remove:
                        InternalChildren.RemoveAt(e.ActualIndex); 
                        break; 

                    case NotifyCollectionChangedAction.Replace: 
                        InternalChildren.RemoveAt(e.ActualIndex);
                        InternalChildren.AddInternal(CreateCell((GridViewColumn)(e.NewItems[0])));
                        break;
 
                    case NotifyCollectionChangedAction.Reset:
                        InternalChildren.Clear(); 
                        break; 

                    default: 
                        break;
                }

                InvalidateMeasure(); 
            }
        }