private static void OnDataGridContextChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            GroupLevelIndicatorPane self = sender as GroupLevelIndicatorPane;

            if (self != null)
            {
                DataGridContext dataGridContext = e.OldValue as DataGridContext;

                //unregister to the old contexts Collection GroupDescriptions Changed event
                if (dataGridContext != null)
                {
                    CollectionChangedEventManager.RemoveListener(dataGridContext.Items.GroupDescriptions, self);
                }

                dataGridContext = e.NewValue as DataGridContext;

                //register to the new contexts Collection GroupDescriptions Changed event
                if (dataGridContext != null)
                {
                    CollectionChangedEventManager.AddListener(dataGridContext.Items.GroupDescriptions, self);
                    self.PrepareDefaultStyleKey(dataGridContext.DataGridControl.GetView());
                }

                self.InvalidateMeasure();
            }
        }
Beispiel #2
0
        protected override Size MeasureOverride(Size availableSize)
        {
            Panel panel = this.GroupLevelIndicatorPaneHost;

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

                if (dataGridContext != null)
                {
                    if (this.GroupLevelIndicatorPaneNeedsRefresh)
                    {
                        //clear all the panel's children!
                        panel.Children.Clear();

                        DataGridContext previousContext        = dataGridContext;
                        DataGridContext runningDataGridContext = dataGridContext.ParentDataGridContext;

                        while (runningDataGridContext != null)
                        {
                            //create a GroupLevelIndicator to create indentation between the GLIPs
                            FrameworkElement newGroupMargin = null;
                            newGroupMargin             = new DetailIndicator();
                            newGroupMargin.DataContext = dataGridContext;

                            object bindingSource = dataGridContext.GetDefaultDetailConfigurationForContext();
                            if (bindingSource == null)
                            {
                                bindingSource = dataGridContext.SourceDetailConfiguration;
                            }

                            //Bind the GroupLevelIndicator`s style to the running DataGridContext`s GroupLevelIndicatorStyle.
                            Binding groupLevelIndicatorStyleBinding = new Binding();
                            groupLevelIndicatorStyleBinding.Path   = new PropertyPath(DetailConfiguration.DetailIndicatorStyleProperty);
                            groupLevelIndicatorStyleBinding.Source = bindingSource;
                            newGroupMargin.SetBinding(StyleProperty, groupLevelIndicatorStyleBinding);

                            //insert the Spacer GroupLevelIndicator in the panel
                            panel.Children.Insert(0, newGroupMargin);

                            if (!runningDataGridContext.AreDetailsFlatten)
                            {
                                //then create the GLIP for the running DataGridContext
                                GroupLevelIndicatorPane newSubGLIP = new GroupLevelIndicatorPane();
                                DataGridControl.SetDataGridContext(newSubGLIP, runningDataGridContext);
                                newSubGLIP.SetIsLeaf(false);
                                GroupLevelIndicatorPane.SetGroupLevel(newSubGLIP, -1);

                                //and insert it in the panel.
                                panel.Children.Insert(0, newSubGLIP);
                            }

                            previousContext        = runningDataGridContext;
                            runningDataGridContext = runningDataGridContext.ParentDataGridContext;
                        } //end of the loop to cycle through the parent contexts.
                    }     // end if GroupLevelIndicatorPaneNeedsRefresh
                }         // end if dataGridContext != null
            }             //end if panel is not null

            return(base.MeasureOverride(availableSize));
        }
        protected override Size MeasureOverride(Size availableSize)
        {
            var panel           = this.GroupLevelIndicatorPaneHost;
            var dataGridContext = DataGridControl.GetDataGridContext(this);

            if ((panel == null) || (dataGridContext == null))
            {
                return(base.MeasureOverride(availableSize));
            }

            var groupDescriptions = DataGridContext.GetGroupDescriptionsHelper(dataGridContext.Items);
            var leafGroupLevel    = GroupLevelIndicatorPane.GetGroupLevel(this);

            // If Indented is true (default), we use the total groupDescriptions.Count for this DataGridContext
            var correctedGroupLevel = (this.Indented == true) ? groupDescriptions.Count : leafGroupLevel;

            // Ensure that the GroupLevel retrieved does not eNequeos the number of group descriptions for the DataGridContext
            correctedGroupLevel = System.Math.Min(correctedGroupLevel, groupDescriptions.Count);

            // Then finally, if the GroupLevel is -1, then indent at maximum.
            if (correctedGroupLevel == -1)
            {
                correctedGroupLevel = groupDescriptions.Count;
            }

            if ((correctedGroupLevel > 0) && (this.AreGroupsFlattened))
            {
                correctedGroupLevel = (this.Indented) ? 1 : 0;
            }

            var children      = panel.Children;
            var childrenCount = children.Count;

            // If we need to add/remove GroupLevelIndicators from the panel
            if (correctedGroupLevel != childrenCount)
            {
                // When grouping change, we take for granted that the group deepness will change,
                // so we initialize DataContext of the margin only in there.

                // Clear all the panel's children!
                children.Clear();

                // Create 1 group margin content presenter for each group level
                for (int i = correctedGroupLevel - 1; i >= 0; i--)
                {
                    GroupLevelIndicator groupMargin = new GroupLevelIndicator();
                    groupMargin.DataContext = dataGridContext.GroupLevelDescriptions[i];
                    children.Insert(0, new GroupLevelIndicator());
                }

                childrenCount = correctedGroupLevel;
                this.SetCurrentIndicatorCount(childrenCount);

                this.InvalidateGroupLevelIndicatorPaneHostPanelMeasure();
            }

            var item = dataGridContext.GetItemFromContainer(this);

            for (int i = 0; i < childrenCount; i++)
            {
                GroupLevelIndicator groupMargin = children[i] as GroupLevelIndicator;

                CollectionViewGroup groupForIndicator = GroupLevelIndicatorPane.GetCollectionViewGroupHelper(
                    dataGridContext, groupDescriptions, item, i);

                GroupConfiguration groupLevelConfig = GroupConfiguration.GetGroupConfiguration(
                    dataGridContext, groupDescriptions, dataGridContext.GroupConfigurationSelector, i, groupForIndicator);

                if (groupLevelConfig != null)
                {
                    Binding groupLevelIndicatorStyleBinding = BindingOperations.GetBinding(groupMargin, GroupLevelIndicator.StyleProperty);

                    if ((groupLevelIndicatorStyleBinding == null) || (groupLevelIndicatorStyleBinding.Source != groupLevelConfig))
                    {
                        groupLevelIndicatorStyleBinding        = new Binding("GroupLevelIndicatorStyle");
                        groupLevelIndicatorStyleBinding.Source = groupLevelConfig;

                        // Use a Converter to manage groupLevelConfig.GroupLevelIndicatorStyle == null
                        // so that an implicit syle won't be overriden by a null style.
                        groupLevelIndicatorStyleBinding.Converter = new GroupLevelIndicatorConverter();

                        groupLevelIndicatorStyleBinding.ConverterParameter = groupMargin;
                        groupMargin.SetBinding(GroupLevelIndicator.StyleProperty, groupLevelIndicatorStyleBinding);
                    }
                }
                else
                {
                    groupMargin.ClearValue(GroupLevelIndicator.StyleProperty);
                }

                // If the ShowIndicators property is False or there is already leafGroupLevel GroupLevelIndicators in the panel,
                // the current newGroupMargin must be hidden.
                if ((!GroupLevelIndicatorPane.GetShowIndicators(this)) || ((i >= leafGroupLevel) && (leafGroupLevel != -1)))
                {
                    groupMargin.Visibility = Visibility.Hidden;
                }
                else
                {
                    groupMargin.Visibility = Visibility.Visible;
                }
            }

            return(base.MeasureOverride(availableSize));
        }