private static HierarchicalGroupByControlNode GetHierarchicalGroupByControlNode(UIElement element)
        {
            HierarchicalGroupByControlNode hierarchicalGroupByControlNode = element as HierarchicalGroupByControlNode;

            if (hierarchicalGroupByControlNode != null)
            {
                return(hierarchicalGroupByControlNode);
            }

            int childCount = VisualTreeHelper.GetChildrenCount(element);

            for (int i = 0; i < childCount; i++)
            {
                UIElement child = VisualTreeHelper.GetChild(element, i) as UIElement;

                if (child != null)
                {
                    hierarchicalGroupByControlNode = HierarchicalGroupByControl.GetHierarchicalGroupByControlNode(child);
                }

                if (hierarchicalGroupByControlNode != null)
                {
                    break;
                }
            }

            return(hierarchicalGroupByControlNode);
        }
        private static void ParentGridControlChangedCallback(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            DataGridControl            parentDataGrid = e.NewValue as DataGridControl;
            HierarchicalGroupByControl groupByControl = ( HierarchicalGroupByControl )sender;

            if (parentDataGrid != null)
            {
                groupByControl.PrepareDefaultStyleKey(parentDataGrid.GetView());
            }
        }
        private static TreeViewItem GetTreeViewItemFromGroupLevelDescription(TreeViewItem rootItem, GroupLevelDescription groupLevelDescription)
        {
            TreeViewItem returned = null;

            Debug.Assert(rootItem != null);
            Debug.Assert(groupLevelDescription != null);

            if (rootItem == null)
            {
                throw new DataGridInternalException("rootItem is null.");
            }

            foreach (object item in rootItem.Items)
            {
                TreeViewItem child = rootItem.ItemContainerGenerator.ContainerFromItem(item) as TreeViewItem;

                Debug.Assert(child != null);
                if (child == null)
                {
                    throw new DataGridInternalException("An item does not contain a valid item.");
                }

                DetailConfiguration detailConfiguration = child.Header as DetailConfiguration;

                if (detailConfiguration == null)
                {
                    throw new DataGridInternalException("An item's DataContext must be a DetailConfiguration except for the top-most HierarchicalGroupByControl, which contains a DataGridContext.");
                }

                if (detailConfiguration.GroupLevelDescriptions.Contains(groupLevelDescription))
                {
                    returned = child;
                    break;
                }

                returned = HierarchicalGroupByControl.GetTreeViewItemFromGroupLevelDescription(child, groupLevelDescription);

                if (returned != null)
                {
                    break;
                }
            }

            return(returned);
        }
        private static TreeViewItem GetTreeViewItemFromGroupLevelDescriptionCollection(TreeViewItem rootItem, GroupLevelDescriptionCollection groupLevelDescriptions)
        {
            TreeViewItem returned = null;

            Debug.Assert(rootItem != null);
            Debug.Assert(groupLevelDescriptions != null);

            if (rootItem == null)
            {
                throw new DataGridInternalException();
            }

            foreach (object item in rootItem.Items)
            {
                TreeViewItem child = rootItem.ItemContainerGenerator.ContainerFromItem(item) as TreeViewItem;

                // It may not be visible
                if (child == null)
                {
                    continue;
                }

                DetailConfiguration detailConfiguration = child.Header as DetailConfiguration;

                if (detailConfiguration == null)
                {
                    throw new DataGridInternalException("The item's DataContext must be a DetailConfiguration except for the top-most HierarchicalGroupByControl, which contains a DataGridContext.");
                }

                if (groupLevelDescriptions == detailConfiguration.GroupLevelDescriptions)
                {
                    returned = child;
                    break;
                }

                returned = HierarchicalGroupByControl.GetTreeViewItemFromGroupLevelDescriptionCollection(child, groupLevelDescriptions);

                if (returned != null)
                {
                    break;
                }
            }

            return(returned);
        }
        private void DragSourceManager_DroppedOutside(object sender, EventArgs e)
        {
            HierarchicalGroupByControlNode hierarchicalGroupByControlNode = HierarchicalGroupByItem.GetParentHierarchicalGroupByControlNode(this);

            if (hierarchicalGroupByControlNode == null)
            {
                throw new DataGridInternalException();
            }

            bool allowGroupingModification = hierarchicalGroupByControlNode.IsGroupingModificationAllowed;

            if (!allowGroupingModification)
            {
                return;
            }

            ObservableCollection <GroupDescription> groupDescriptions = this.ParentGroupDescriptions;

            if (groupDescriptions != null)
            {
                // Get the HierarchicalGroupByControl before removing us from it
                HierarchicalGroupByControl parentGBC = GroupingHelper.GetHierarchicalGroupByControl(this);

                GroupLevelDescription groupLevelDescription = this.Content as GroupLevelDescription;

                DataGridContext dataGridContext = DataGridControl.GetDataGridContext(this);

                DataGridControl parentDataGridControl = (dataGridContext != null)
          ? dataGridContext.DataGridControl
          : null;

                GroupingHelper.RemoveGroupDescription(groupDescriptions, groupLevelDescription, parentDataGridControl);

                // Notify groups have changed for NoGroupContent
                parentGBC.UpdateHasGroups();

                // Update the HasGroups property
                Debug.Assert(parentGBC != null);
                if (parentGBC == null)
                {
                    throw new DataGridInternalException("The hierarchical group-by item must be rooted by a HierarchicalGroupByControl.");
                }
            }
        }
        void IDropTarget.Drop(UIElement draggedElement)
        {
            ColumnManagerCell cell = draggedElement as ColumnManagerCell;

            if (cell == null)
            {
                return;
            }

            HierarchicalGroupByControl parentGBC = GroupingHelper.GetHierarchicalGroupByControl(this);

            if (parentGBC == null)
            {
                throw new DataGridInternalException("The hierarchical group-by control node must be rooted by a HierarchicalGroupByControl.");
            }

            DataGridContext dataGridContext = DataGridControl.GetDataGridContext(this);

            DataGridControl parentGrid = (dataGridContext != null)
        ? dataGridContext.DataGridControl
        : null;

            GroupingHelper.AppendNewGroupFromColumnManagerCell(cell, parentGrid);

            // Notify groups have changed for NoGroupContent
            parentGBC.UpdateHasGroups();

            HierarchicalGroupByControlNode hierarchicalGroupByControlNode = parentGBC.GetHierarchicalGroupByControlNodeFromColumnManagerCell(cell);

            if (hierarchicalGroupByControlNode == null)
            {
                return;
            }

            hierarchicalGroupByControlNode.HideFarDropMark(cell);

            this.HideFarDropMark();
        }
        void IDropTarget.DragLeave(UIElement draggedElement)
        {
            ColumnManagerCell cell = draggedElement as ColumnManagerCell;

            if (cell != null)
            {
                HierarchicalGroupByControl parentGBC = GroupingHelper.GetHierarchicalGroupByControl(this);

                if (parentGBC == null)
                {
                    throw new DataGridInternalException("The hierarchical group-by control node must be rooted by a HierarchicalGroupByControl.");
                }

                HierarchicalGroupByControlNode hierarchicalGroupByControlNode = parentGBC.GetHierarchicalGroupByControlNodeFromColumnManagerCell(cell);

                if (hierarchicalGroupByControlNode == null)
                {
                    throw new DataGridInternalException("A HierarchicalGroupByControlNode must exist for every level.");
                }

                hierarchicalGroupByControlNode.HideFarDropMark(cell);
            }
            else
            {
                HierarchicalGroupByItem hierarchicalGroupByItem = draggedElement as HierarchicalGroupByItem;
                if (hierarchicalGroupByItem == null)
                {
                    return;
                }

                HierarchicalGroupByControlNode draggedHierarchicalGroupByControlNode = HierarchicalGroupByItem.GetParentHierarchicalGroupByControlNode(hierarchicalGroupByItem);

                if (draggedHierarchicalGroupByControlNode == null)
                {
                    throw new DataGridInternalException("draggedHierarchicalGroupByControlNode is null.");
                }

                if (draggedHierarchicalGroupByControlNode.GroupLevelDescriptions == this.GroupLevelDescriptions)
                {
                    this.HideFarDropMark();
                }
                else
                {
                    // This HierarchicalGroupByItem does not belong this parent HierarchicalGroupByControlNode, display the DropMark on the correct one
                    HierarchicalGroupByControl parentGBC = GroupingHelper.GetHierarchicalGroupByControl(this);

                    Debug.Assert(parentGBC != null);
                    if (parentGBC == null)
                    {
                        throw new DataGridInternalException("The hierarchical group-by control node must be rooted by a HierarchicalGroupByControl");
                    }

                    HierarchicalGroupByControlNode hierarchicalGroupByControlNode = parentGBC.GetHierarchicalGroupByControlNodeFromHierarchicalGroupByItem(hierarchicalGroupByItem);

                    Debug.Assert(hierarchicalGroupByControlNode != null, "CanDrop should have returned false");
                    if (hierarchicalGroupByControlNode == null)
                    {
                        throw new DataGridInternalException("A HierarchicalGroupByControlNode must exist for every level.");
                    }

                    hierarchicalGroupByControlNode.HideFarDropMark();
                }
            }
        }
        bool IDropTarget.CanDropElement(UIElement draggedElement)
        {
            ColumnManagerCell       cell = null;
            HierarchicalGroupByItem hierarchicalGroupByItem = null;
            bool canDrop = this.AllowGroupingModification;

            if (canDrop)
            {
                cell = draggedElement as ColumnManagerCell;

                if (cell != null)
                {
                    ColumnBase parentColumn = cell.ParentColumn;

                    if ((parentColumn == null) || (!parentColumn.AllowGroup))
                    {
                        return(false);
                    }

                    // Check if already grouped using the cell's DataGridContext
                    canDrop = !GroupingHelper.IsAlreadyGroupedBy(cell);

                    if (canDrop)
                    {
                        // Get the HierarchicalGroupByControl for this HierarchicalGroupByControlNode
                        HierarchicalGroupByControl parentGBC = GroupingHelper.GetHierarchicalGroupByControl(this);

                        if (parentGBC == null)
                        {
                            throw new DataGridInternalException("The hierarchical group-by control node must be rooted by a HierarchicalGroupByControl.");
                        }

                        DataGridContext parentGBCDataGridContext = DataGridControl.GetDataGridContext(parentGBC);

                        Debug.Assert(parentGBCDataGridContext != null);

                        if (parentGBCDataGridContext.Items != null)
                        {
                            canDrop = parentGBCDataGridContext.Items.CanGroup;
                        }

                        if (canDrop)
                        {
                            canDrop = GroupingHelper.IsColumnManagerCellInDataGridContext(parentGBCDataGridContext, cell);

                            if (canDrop == true)
                            {
                                canDrop = GroupingHelper.ValidateMaxGroupDescriptions(DataGridControl.GetDataGridContext(draggedElement));
                            }
                        }
                    }
                }
                else
                {
                    hierarchicalGroupByItem = draggedElement as HierarchicalGroupByItem;

                    if (hierarchicalGroupByItem == null)
                    {
                        canDrop = false;
                    }

                    if (canDrop)
                    {
                        HierarchicalGroupByControl parentGBC = GroupingHelper.GetHierarchicalGroupByControl(this);

                        if (parentGBC == null)
                        {
                            throw new DataGridInternalException("The hierarchical group-by control node must be rooted by a HierarchicalGroupByControl.");
                        }

                        // Try to get the HierarchicalGroupByControlNode in which this HierarchicalGroupByItem can be added using the parent HierarchicalGroupByControl => null it can't
                        HierarchicalGroupByControlNode draggedHierarchicalGroupByControlNode = parentGBC.GetHierarchicalGroupByControlNodeFromHierarchicalGroupByItem(hierarchicalGroupByItem);

                        if (draggedHierarchicalGroupByControlNode == null)
                        {
                            canDrop = false;
                        }
                    }
                }
            }

            bool returnedValue = ((cell != null) || (hierarchicalGroupByItem != null)) &&// ColumnManagerCell or HierarchicalGroupByItem
                                 (canDrop);


            return(returnedValue);
        }
        void IDropTarget.Drop(UIElement draggedElement)
        {
            ColumnManagerCell draggedColumnManagerCell = draggedElement as ColumnManagerCell;

            if (m_dropMarkAdorner != null)
            {
                GroupLevelDescription draggedOverGroupLevelDescription = this.Content as GroupLevelDescription;

                DropMarkAlignment alignment = m_dropMarkAdorner.Alignment;
                this.HideDropMark();

                if (draggedColumnManagerCell != null)
                {
                    DataGridContext dataGridContext = DataGridControl.GetDataGridContext(this);

                    DataGridControl parentGrid = (dataGridContext != null)
            ? dataGridContext.DataGridControl
            : null;

                    GroupingHelper.AddNewGroupFromColumnManagerCell(draggedColumnManagerCell, draggedOverGroupLevelDescription, alignment, parentGrid);
                }
                else
                {
                    HierarchicalGroupByItem draggedGroupByItem = draggedElement as HierarchicalGroupByItem;

                    if (draggedGroupByItem == null)
                    {
                        return;
                    }

                    GroupLevelDescription draggedGroupLevelDescription = draggedGroupByItem.Content as GroupLevelDescription;

                    DataGridContext dataGridContext = DataGridControl.GetDataGridContext(this);

                    DataGridControl parentDataGridControl = (dataGridContext != null)
            ? dataGridContext.DataGridControl
            : null;

                    GroupLevelDescription destinationGroupLevelDescription = this.Content as GroupLevelDescription;

                    GroupingHelper.MoveGroupDescription(this.ParentColumns, this.ParentGroupDescriptions,
                                                        destinationGroupLevelDescription, alignment,
                                                        draggedGroupLevelDescription, parentDataGridControl);
                }
            }
            else
            {
                // We try to add a new Group which is not in the current GroupLevelDescriptions
                if (draggedColumnManagerCell == null)
                {
                    return;
                }

                DataGridContext dataGridContext = DataGridControl.GetDataGridContext(this);

                DataGridControl parentGrid = (dataGridContext != null)
          ? dataGridContext.DataGridControl
          : null;

                GroupingHelper.AppendNewGroupFromColumnManagerCell(draggedColumnManagerCell, parentGrid);
            }

            HierarchicalGroupByControl parentGBC = GroupingHelper.GetHierarchicalGroupByControl(this);

            Debug.Assert(parentGBC != null);
            if (parentGBC == null)
            {
                throw new DataGridInternalException("A hierarchical group-by item must be rooted by a HierarchicalGroupByControl.");
            }

            // Notify groups have changed for NoGroupContent
            parentGBC.UpdateHasGroups();
        }
        void IDropTarget.DragOver(UIElement draggedElement, Point mousePosition)
        {
            ColumnManagerCell cell = draggedElement as ColumnManagerCell;

            if (cell != null)
            {
                DataGridContext draggedCellDataGridContext = DataGridControl.GetDataGridContext(cell);

                HierarchicalGroupByControlNode draggedOverHierarchicalGroupByControlNode = HierarchicalGroupByItem.GetParentHierarchicalGroupByControlNode(this);

                if (draggedCellDataGridContext == null)
                {
                    throw new DataGridInternalException("A ColumnManagerCell must have a DataGridContext.");
                }

                if (draggedOverHierarchicalGroupByControlNode == null)
                {
                    throw new DataGridInternalException();
                }

                if (draggedOverHierarchicalGroupByControlNode.GroupLevelDescriptions == draggedCellDataGridContext.GroupLevelDescriptions)
                {
                    this.ShowDropMark(mousePosition);
                }
                else
                {
                    // This ColumnManagerCell does not belong this parent HierarchicalGroupByControlNode, display the DropMark on the correct one
                    HierarchicalGroupByControl parentGBC = GroupingHelper.GetHierarchicalGroupByControl(draggedOverHierarchicalGroupByControlNode);

                    if (parentGBC == null)
                    {
                        throw new DataGridInternalException("The hierarchical group-by item must be rooted by a HierarchicalGroupByControl.");
                    }

                    HierarchicalGroupByControlNode hierarchicalGroupByControlNode = parentGBC.GetHierarchicalGroupByControlNodeFromColumnManagerCell(cell);

                    Debug.Assert(hierarchicalGroupByControlNode != null, "CanDrop should have returned false");
                    if (hierarchicalGroupByControlNode == null)
                    {
                        throw new DataGridInternalException("A HierarchicalGroupByControlNode must exist for every level.");
                    }

                    hierarchicalGroupByControlNode.ShowFarDropMark(cell, mousePosition);
                }
            }
            else
            {
                HierarchicalGroupByItem hierarchicalGroupByItem = draggedElement as HierarchicalGroupByItem;

                if (hierarchicalGroupByItem == null)
                {
                    return;
                }

                HierarchicalGroupByControlNode draggedHierarchicalGroupByControlNode = HierarchicalGroupByItem.GetParentHierarchicalGroupByControlNode(hierarchicalGroupByItem);

                HierarchicalGroupByControlNode draggedOverHierarchicalGroupByControlNode = HierarchicalGroupByItem.GetParentHierarchicalGroupByControlNode(this);

                if (draggedHierarchicalGroupByControlNode == null)
                {
                    throw new DataGridInternalException();
                }

                if (draggedOverHierarchicalGroupByControlNode == null)
                {
                    throw new DataGridInternalException();
                }

                if (draggedHierarchicalGroupByControlNode.GroupLevelDescriptions == draggedOverHierarchicalGroupByControlNode.GroupLevelDescriptions)
                {
                    this.ShowDropMark(mousePosition);
                }
                else
                {
                    // This HierarchicalGroupByItem does not belong this parent HierarchicalGroupByControlNode, display the DropMark on the correct one
                    HierarchicalGroupByControl parentGBC = GroupingHelper.GetHierarchicalGroupByControl(draggedOverHierarchicalGroupByControlNode);

                    if (parentGBC == null)
                    {
                        throw new DataGridInternalException("A hierarchical group-by item must be rooted by a HierarchicalGroupByControl.");
                    }

                    HierarchicalGroupByControlNode hierarchicalGroupByControlNode = parentGBC.GetHierarchicalGroupByControlNodeFromHierarchicalGroupByItem(hierarchicalGroupByItem);

                    Debug.Assert(hierarchicalGroupByControlNode != null, "CanDrop should have returned false");
                    if (hierarchicalGroupByControlNode == null)
                    {
                        throw new DataGridInternalException("A HierarchicalGroupByControlNode must exist for every level.");
                    }

                    hierarchicalGroupByControlNode.ShowFarDropMark(mousePosition);
                }
            }
        }
        internal HierarchicalGroupByControlNode GetHierarchicalGroupByControlNodeFromHierarchicalGroupByItem(HierarchicalGroupByItem hierarchicalGroupByItem)
        {
            Debug.Assert(hierarchicalGroupByItem != null);
            if (hierarchicalGroupByItem == null)
            {
                return(null);
            }

            TreeView treeView = this.GetTemplateChild(@"PART_HierarchicalGroupByControlTreeView") as TreeView;

            if (treeView == null)
            {
                return(null);
            }

            if (treeView.Items.Count == 0)
            {
                throw new DataGridInternalException("The HierarchicalGroupByControl should contain at least one grouping level.");
            }

            // The first item is always the top level HierarchicalGroupByControlNode
            TreeViewItem rootItem = treeView.ItemContainerGenerator.ContainerFromItem(treeView.Items[0]) as TreeViewItem;

            if (rootItem == null)
            {
                throw new DataGridInternalException("The root item is null.");
            }

            GroupLevelDescription detailGroupLevelDescription = hierarchicalGroupByItem.Content as GroupLevelDescription;

            Debug.Assert(detailGroupLevelDescription != null);

            TreeViewItem dropMarkedTreeViewItem = null;

            DataGridContext rootDataGridContext = rootItem.Header as DataGridContext;

            Debug.Assert(rootDataGridContext != null);

            if (rootDataGridContext.GroupLevelDescriptions.Contains(detailGroupLevelDescription))
            {
                dropMarkedTreeViewItem = rootItem;
            }
            else
            {
                dropMarkedTreeViewItem = HierarchicalGroupByControl.GetTreeViewItemFromGroupLevelDescription(rootItem, detailGroupLevelDescription);
            }


            // If null, it means the cell does not belong to this detail
            if (dropMarkedTreeViewItem == null)
            {
                return(null);
            }

            ContentPresenter treeViewItemHeader = dropMarkedTreeViewItem.Template.FindName("PART_Header", dropMarkedTreeViewItem) as ContentPresenter;

            Debug.Assert(treeViewItemHeader != null);
            if (treeViewItemHeader == null)
            {
                throw new DataGridInternalException("An error occurred while retrieving the PART_Header template part of an item containing a HierarchicalGroupByControlNode.");
            }

            HierarchicalGroupByControlNode hierarchicalGroupByControlNode = HierarchicalGroupByControl.GetHierarchicalGroupByControlNode(treeViewItemHeader);

            return(hierarchicalGroupByControlNode);
        }
        internal HierarchicalGroupByControlNode GetHierarchicalGroupByControlNodeFromColumnManagerCell(ColumnManagerCell cell)
        {
            Debug.Assert(cell != null);
            if (cell == null)
            {
                return(null);
            }

            DataGridContext cellDataGridContext = DataGridControl.GetDataGridContext(cell);

            if (cellDataGridContext == null)
            {
                throw new DataGridInternalException("A DataGridContext cannot be null on ColumnManagerCell.");
            }

            TreeView treeView = this.GetTemplateChild(@"PART_HierarchicalGroupByControlTreeView") as TreeView;

            if (treeView == null)
            {
                return(null);
            }

            if (treeView.Items.Count == 0)
            {
                throw new DataGridInternalException("The HierarchicalGroupByControl should contain at least one grouping level.");
            }

            // The first item is always the top level HierarchicalGroupByControlNode
            TreeViewItem rootItem = treeView.ItemContainerGenerator.ContainerFromItem(treeView.Items[0]) as TreeViewItem;

            // It may not be visible
            if (rootItem == null)
            {
                return(null);
            }

            TreeViewItem dropMarkedTreeViewItem = null;

            DataGridContext rootDataGridContext = rootItem.Header as DataGridContext;

            if ((rootDataGridContext != null) && (rootDataGridContext.GroupLevelDescriptions == cellDataGridContext.GroupLevelDescriptions))
            {
                dropMarkedTreeViewItem = rootItem;
            }
            else
            {
                GroupLevelDescriptionCollection groupLevelDescriptions = cellDataGridContext.GroupLevelDescriptions;

                dropMarkedTreeViewItem = HierarchicalGroupByControl.GetTreeViewItemFromGroupLevelDescriptionCollection(rootItem, groupLevelDescriptions);
            }

            // If null, it means the cell does not belong to this detail
            if (dropMarkedTreeViewItem == null)
            {
                return(null);
            }

            ContentPresenter treeViewItemHeader = dropMarkedTreeViewItem.Template.FindName("PART_Header", dropMarkedTreeViewItem) as ContentPresenter;

            // It may not be visible
            if (treeViewItemHeader == null)
            {
                return(null);
            }

            HierarchicalGroupByControlNode hierarchicalGroupByControlNode = HierarchicalGroupByControl.GetHierarchicalGroupByControlNode(treeViewItemHeader);

            return(hierarchicalGroupByControlNode);
        }