Example #1
0
        internal void ToggleExpandCollapse(bool isVisible, bool setCurrent)
        {
            if (RowGroupInfo.CollectionViewGroup.ItemCount != 0)
            {
                if (OwningGrid == null)
                {
                    // Do these even if the OwningGrid is null in case it could improve the Designer experience for a standalone DataGridRowGroupHeader
                    RowGroupInfo.IsVisible = isVisible;
                }
                else if (RowGroupInfo.IsVisible != isVisible)
                {
                    OwningGrid.OnRowGroupHeaderToggled(this, isVisible, setCurrent);
                }

                EnsureExpanderButtonIsChecked();

                ApplyState(true /*useTransitions*/);
            }
        }
        //TODO DragEvents
        //TODO MouseCapture
        internal void OnMouseLeftButtonUp(ref bool handled, PointerEventArgs args, Point mousePosition, Point mousePositionHeaders)
        {
            IsPressed = false;

            if (OwningGrid != null && OwningGrid.ColumnHeaders != null)
            {
                if (_dragMode == DragMode.MouseDown)
                {
                   OnMouseLeftButtonUp_Click(args.InputModifiers, ref handled);
                }
                else if (_dragMode == DragMode.Reorder)
                {
                    // Find header we're hovering over
                    int targetIndex = GetReorderingTargetDisplayIndex(mousePositionHeaders);

                    if (((!OwningColumn.IsFrozen && targetIndex >= OwningGrid.FrozenColumnCount)
                          || (OwningColumn.IsFrozen && targetIndex < OwningGrid.FrozenColumnCount)))
                    {
                        OwningColumn.DisplayIndex = targetIndex;

                        DataGridColumnEventArgs ea = new DataGridColumnEventArgs(OwningColumn);
                        OwningGrid.OnColumnReordered(ea);
                    }

                    //DragCompletedEventArgs dragCompletedEventArgs = new DragCompletedEventArgs(mousePosition.X - _dragStart.Value.X, mousePosition.Y - _dragStart.Value.Y, false);
                    //OwningGrid.OnColumnHeaderDragCompleted(dragCompletedEventArgs);
                }
                //else if (_dragMode == DragMode.Drag)
                //{
                //    DragCompletedEventArgs dragCompletedEventArgs = new DragCompletedEventArgs(0, 0, false);
                //    OwningGrid.OnColumnHeaderDragCompleted(dragCompletedEventArgs);
                //}

                SetDragCursor(mousePosition);

                // Variables that track drag mode states get reset in DataGridColumnHeader_LostMouseCapture
                args.Device.Capture(null);
                OnLostMouseCapture();
                _dragMode = DragMode.None;
                handled = true;
            }
        }
Example #3
0
        private void DataGridRow_PointerPressed(PointerPressedEventArgs e)
        {
            if (e.GetCurrentPoint(this).Properties.IsLeftButtonPressed)
            {
                return;
            }

            if (OwningGrid != null)
            {
                OwningGrid.IsDoubleClickRecordsClickOnCall(this);
                if (OwningGrid.UpdatedStateOnMouseLeftButtonDown)
                {
                    OwningGrid.UpdatedStateOnMouseLeftButtonDown = false;
                }
                else
                {
                    e.Handled = OwningGrid.UpdateStateOnMouseLeftButtonDown(e, -1, Slot, false);
                }
            }
        }
 private void OwningGrid_CurrentCellChanged(object sender, EventArgs e)
 {
     if (_currentCheckBox != null)
     {
         _currentCheckBox.IsEnabled = false;
     }
     if (OwningGrid != null && OwningGrid.CurrentColumn == this &&
         OwningGrid.IsSlotVisible(OwningGrid.CurrentSlot))
     {
         if (OwningGrid.DisplayData.GetDisplayedElement(OwningGrid.CurrentSlot) is DataGridRow row)
         {
             CheckBox checkBox = GetCellContent(row) as CheckBox;
             if (checkBox != null)
             {
                 checkBox.IsEnabled = true;
             }
             _currentCheckBox = checkBox;
         }
     }
 }
Example #5
0
 //TODO TabStop
 private void DataGridRowGroupHeader_PointerPressed(PointerPressedEventArgs e)
 {
     if (OwningGrid != null && e.GetCurrentPoint(this).Properties.IsLeftButtonPressed)
     {
         if (OwningGrid.IsDoubleClickRecordsClickOnCall(this) && !e.Handled)
         {
             ToggleExpandCollapse(!RowGroupInfo.IsVisible, true);
             e.Handled = true;
         }
         else
         {
             //if (!e.Handled && OwningGrid.IsTabStop)
             if (!e.Handled)
             {
                 OwningGrid.Focus();
             }
             e.Handled = OwningGrid.UpdateStateOnMouseLeftButtonDown(e, OwningGrid.CurrentColumnIndex, RowGroupInfo.Slot, allowEdit: false);
         }
     }
 }
        internal void UpdateIndexes()
        {
            _oldSelectedSlotsTable.Clear();
            _selectedSlotsTable.Clear();

            if (OwningGrid.DataConnection.DataSource == null)
            {
                if (SelectedItemsCache.Count > 0)
                {
                    OwningGrid.SelectionHasChanged = true;
                    SelectedItemsCache.Clear();
                }
            }
            else
            {
                List <object> tempSelectedItemsCache = new List <object>();
                foreach (object item in _selectedItemsCache)
                {
                    int index = OwningGrid.DataConnection.IndexOf(item);
                    if (index != -1)
                    {
                        tempSelectedItemsCache.Add(item);
                        _selectedSlotsTable.AddValue(OwningGrid.SlotFromRowIndex(index), true);
                    }
                }
                foreach (object item in _oldSelectedItemsCache)
                {
                    int index = OwningGrid.DataConnection.IndexOf(item);
                    if (index == -1)
                    {
                        OwningGrid.SelectionHasChanged = true;
                    }
                    else
                    {
                        _oldSelectedSlotsTable.AddValue(OwningGrid.SlotFromRowIndex(index), true);
                    }
                }
                _selectedItemsCache = tempSelectedItemsCache;
            }
        }
Example #7
0
        private void OnMouseMove_Resize(ref bool handled, Point mousePositionHeaders)
        {
            if (handled)
            {
                return;
            }

            if (_dragMode == DragMode.Resize && _dragColumn != null && _dragStart.HasValue)
            {
                // resize column

                double mouseDelta   = mousePositionHeaders.X - _dragStart.Value.X;
                double desiredWidth = _originalWidth + mouseDelta;

                desiredWidth = Math.Max(_dragColumn.ActualMinWidth, Math.Min(_dragColumn.ActualMaxWidth, desiredWidth));
                _dragColumn.Resize(_dragColumn.Width.Value, _dragColumn.Width.UnitType, _dragColumn.Width.DesiredValue, desiredWidth, true);

                OwningGrid.UpdateHorizontalOffset(_originalHorizontalOffset);

                handled = true;
            }
        }
Example #8
0
 private void DataGridCell_MouseLeftButtonDown(object sender, PointerPressedEventArgs e)
 {
     if (!e.Handled)
     {
         // OwningGrid is null for TopLeftHeaderCell and TopRightHeaderCell because they have no OwningRow
         if (this.OwningGrid != null)
         {
             if (this.OwningRow != null)
             {
                 Debug.Assert(sender is DataGridCell);
                 Debug.Assert(sender == this);
                 e.Handled = this.OwningGrid.UpdateStateOnMouseLeftButtonDown(e, this.ColumnIndex, this.RowIndex);
             }
             if (this.OwningGrid.IsTabStop)
             {
                 //  bool success = this.
                 OwningGrid.Focus();
                 //Debug.Assert(success);
             }
         }
     }
 }
Example #9
0
        //TODO TabStop
        private void DataGridRowHeader_PointerPressed(object sender, PointerPressedEventArgs e)
        {
            if (e.MouseButton != MouseButton.Left)
            {
                return;
            }

            if (OwningGrid != null)
            {
                if (!e.Handled)
                //if (!e.Handled && OwningGrid.IsTabStop)
                {
                    OwningGrid.Focus();
                }
                if (OwningRow != null)
                {
                    Debug.Assert(sender is DataGridRowHeader);
                    Debug.Assert(sender == this);
                    e.Handled = OwningGrid.UpdateStateOnMouseLeftButtonDown(e, -1, Slot, false);
                    OwningGrid.UpdatedStateOnMouseLeftButtonDown = true;
                }
            }
        }
 internal void SelectSlot(int slot, bool select)
 {
     if (OwningGrid.RowGroupHeadersTable.Contains(slot))
     {
         return;
     }
     if (select)
     {
         if (!_selectedSlotsTable.Contains(slot))
         {
             _selectedItemsCache.Add(OwningGrid.DataConnection.GetDataItem(OwningGrid.RowIndexFromSlot(slot)));
         }
         _selectedSlotsTable.AddValue(slot, true);
     }
     else
     {
         if (_selectedSlotsTable.Contains(slot))
         {
             _selectedItemsCache.Remove(OwningGrid.DataConnection.GetDataItem(OwningGrid.RowIndexFromSlot(slot)));
         }
         _selectedSlotsTable.RemoveValue(slot);
     }
 }
        public void RemoveAt(int index)
        {
            if (OwningGrid.SelectionMode == DataGridSelectionMode.Single)
            {
                throw DataGridError.DataGridSelectedItemsCollection.CannotChangeSelectedItemsCollectionInSingleMode();
            }

            if (index < 0 || index >= _selectedSlotsTable.IndexCount)
            {
                throw DataGridError.DataGrid.ValueMustBeBetween("index", "Index", 0, true, _selectedSlotsTable.IndexCount, false);
            }
            int rowIndex = _selectedSlotsTable.GetNthIndex(index);

            Debug.Assert(rowIndex > -1);

            if (rowIndex == OwningGrid.CurrentSlot &&
                !OwningGrid.CommitEdit(DataGridEditingUnit.Row, true /*exitEditing*/))
            {
                // Edited value couldn't be committed or aborted
                return;
            }

            OwningGrid.SetRowSelection(rowIndex, false /*isSelected*/, false /*setAnchorSlot*/);
        }
        public void Remove(object dataItem)
        {
            if (OwningGrid.SelectionMode == DataGridSelectionMode.Single)
            {
                throw DataGridError.DataGridSelectedItemsCollection.CannotChangeSelectedItemsCollectionInSingleMode();
            }

            int itemIndex = OwningGrid.DataConnection.IndexOf(dataItem);

            if (itemIndex == -1)
            {
                return;
            }
            Debug.Assert(itemIndex >= 0);

            if (itemIndex == OwningGrid.CurrentSlot &&
                !OwningGrid.CommitEdit(DataGridEditingUnit.Row, true /*exitEditing*/))
            {
                // Edited value couldn't be committed or aborted
                return;
            }

            OwningGrid.SetRowSelection(itemIndex, false /*isSelected*/, false /*setAnchorSlot*/);
        }
Example #13
0
        //TODO TabStop
        private void DataGridRowHeader_PointerPressed(object sender, PointerPressedEventArgs e)
        {
            if (OwningGrid == null)
            {
                return;
            }

            if (e.GetCurrentPoint(this).Properties.IsLeftButtonPressed)
            {
                if (!e.Handled)
                //if (!e.Handled && OwningGrid.IsTabStop)
                {
                    OwningGrid.Focus();
                }
                if (OwningRow != null)
                {
                    Debug.Assert(sender is DataGridRowHeader);
                    Debug.Assert(sender == this);
                    e.Handled = OwningGrid.UpdateStateOnMouseLeftButtonDown(e, -1, Slot, false);
                    OwningGrid.UpdatedStateOnMouseLeftButtonDown = true;
                }
            }
            else if (e.GetCurrentPoint(this).Properties.IsRightButtonPressed)
            {
                if (!e.Handled)
                {
                    OwningGrid.Focus();
                }
                if (OwningRow != null)
                {
                    Debug.Assert(sender is DataGridRowHeader);
                    Debug.Assert(sender == this);
                    e.Handled = OwningGrid.UpdateStateOnMouseRightButtonDown(e, -1, Slot, false);
                }
            }
        }
        internal void SelectSlots(int startSlot, int endSlot, bool select)
        {
            int itemSlot    = OwningGrid.RowGroupHeadersTable.GetNextGap(startSlot - 1);
            int endItemSlot = OwningGrid.RowGroupHeadersTable.GetPreviousGap(endSlot + 1);

            if (select)
            {
                while (itemSlot <= endItemSlot)
                {
                    // Add the newly selected item slots by skipping over the RowGroupHeaderSlots
                    int nextRowGroupHeaderSlot = OwningGrid.RowGroupHeadersTable.GetNextIndex(itemSlot);
                    int lastItemSlot           = nextRowGroupHeaderSlot == -1 ? endItemSlot : Math.Min(endItemSlot, nextRowGroupHeaderSlot - 1);
                    for (int slot = itemSlot; slot <= lastItemSlot; slot++)
                    {
                        if (!_selectedSlotsTable.Contains(slot))
                        {
                            _selectedItemsCache.Add(OwningGrid.DataConnection.GetDataItem(OwningGrid.RowIndexFromSlot(slot)));
                        }
                    }
                    _selectedSlotsTable.AddValues(itemSlot, lastItemSlot - itemSlot + 1, true);
                    itemSlot = OwningGrid.RowGroupHeadersTable.GetNextGap(lastItemSlot);
                }
            }
            else
            {
                while (itemSlot <= endItemSlot)
                {
                    // Remove the unselected item slots by skipping over the RowGroupHeaderSlots
                    int nextRowGroupHeaderSlot = OwningGrid.RowGroupHeadersTable.GetNextIndex(itemSlot);
                    int lastItemSlot           = nextRowGroupHeaderSlot == -1 ? endItemSlot : Math.Min(endItemSlot, nextRowGroupHeaderSlot - 1);
                    for (int slot = itemSlot; slot <= lastItemSlot; slot++)
                    {
                        if (_selectedSlotsTable.Contains(slot))
                        {
                            _selectedItemsCache.Remove(OwningGrid.DataConnection.GetDataItem(OwningGrid.RowIndexFromSlot(slot)));
                        }
                    }
                    _selectedSlotsTable.RemoveValues(itemSlot, lastItemSlot - itemSlot + 1);
                    itemSlot = OwningGrid.RowGroupHeadersTable.GetNextGap(lastItemSlot);
                }
            }
        }
        /// <summary>
        /// Called by the DataGrid control when this column asks for its elements to be updated, because a property changed.
        /// </summary>
        protected internal override void RefreshCellContent(FrameworkElement element, Brush computedRowForeground, string propertyName)
        {
            if (element == null)
            {
                throw new ArgumentNullException(nameof(element));
            }

            var comboBox = element as ComboBox;

            if (comboBox == null)
            {
                var textBlock = element as TextBlock;
                if (textBlock == null)
                {
                    throw DataGridError.DataGrid.ValueIsNotAnInstanceOfEitherOr(nameof(element), typeof(ComboBox), typeof(TextBlock));
                }

                if (propertyName == DATAGRIDCOMBOBOXCOLUMN_fontFamilyName)
                {
                    textBlock.FontFamily = FontFamily;
                }
                else if (propertyName == DATAGRIDCOMBOBOXCOLUMN_fontSizeName)
                {
                    SetTextFontSize(textBlock, TextBlock.FontSizeProperty);
                }
                else if (propertyName == DATAGRIDCOMBOBOXCOLUMN_fontStyleName)
                {
                    textBlock.FontStyle = FontStyle;
                }
                else if (propertyName == DATAGRIDCOMBOBOXCOLUMN_fontWeightName)
                {
                    textBlock.FontWeight = FontWeight;
                }
                else if (propertyName == DATAGRIDCOMBOBOXCOLUMN_foregroundName)
                {
                    RefreshForeground(textBlock, computedRowForeground);
                }
                else if (propertyName == DATAGRIDCOMBOBOXCOLUMN_itemsSourceName)
                {
                    OwningGrid.OnColumnBindingChanged(this);
                }
                else
                {
                    if (FontFamily != null)
                    {
                        textBlock.FontFamily = FontFamily;
                    }

                    SetTextFontSize(textBlock, TextBlock.FontSizeProperty);
                    textBlock.FontStyle  = FontStyle;
                    textBlock.FontWeight = FontWeight;
                    RefreshForeground(textBlock, computedRowForeground);
                }

                return;
            }

            if (propertyName == DATAGRIDCOMBOBOXCOLUMN_fontFamilyName)
            {
                comboBox.FontFamily = FontFamily;
            }
            else if (propertyName == DATAGRIDCOMBOBOXCOLUMN_fontSizeName)
            {
                SetTextFontSize(comboBox, ComboBox.FontSizeProperty);
            }
            else if (propertyName == DATAGRIDCOMBOBOXCOLUMN_fontStyleName)
            {
                comboBox.FontStyle = FontStyle;
            }
            else if (propertyName == DATAGRIDCOMBOBOXCOLUMN_fontWeightName)
            {
                comboBox.FontWeight = FontWeight;
            }
            else if (propertyName == DATAGRIDCOMBOBOXCOLUMN_foregroundName)
            {
                RefreshForeground(comboBox, computedRowForeground);
            }
            else
            {
                if (FontFamily != null)
                {
                    comboBox.FontFamily = FontFamily;
                }

                SetTextFontSize(comboBox, ComboBox.FontSizeProperty);
                comboBox.FontStyle  = FontStyle;
                comboBox.FontWeight = FontWeight;
                RefreshForeground(comboBox, computedRowForeground);
            }
        }
Example #16
0
 private void OnRowDetailsChanged()
 {
     OwningGrid?.OnRowDetailsChanged();
 }
        //TODO GroupSorting
        internal void ProcessSort(KeyModifiers keyModifiers, ListSortDirection?forcedDirection = null)
        {
            // if we can sort:
            //  - AllowUserToSortColumns and CanSort are true, and
            //  - OwningColumn is bound
            // then try to sort
            if (OwningColumn != null &&
                OwningGrid != null &&
                OwningGrid.EditingRow == null &&
                OwningColumn != OwningGrid.ColumnsInternal.FillerColumn &&
                OwningGrid.CanUserSortColumns &&
                OwningColumn.CanUserSort)
            {
                var ea = new DataGridColumnEventArgs(OwningColumn);
                OwningGrid.OnColumnSorting(ea);

                if (!ea.Handled && OwningGrid.DataConnection.AllowSort && OwningGrid.DataConnection.SortDescriptions != null)
                {
                    // - DataConnection.AllowSort is true, and
                    // - SortDescriptionsCollection exists, and
                    // - the column's data type is comparable

                    DataGrid owningGrid = OwningGrid;
                    DataGridSortDescription newSort;

                    KeyboardHelper.GetMetaKeyState(keyModifiers, out bool ctrl, out bool shift);

                    DataGridSortDescription sort           = OwningColumn.GetSortDescription();
                    IDataGridCollectionView collectionView = owningGrid.DataConnection.CollectionView;
                    Debug.Assert(collectionView != null);

                    using (collectionView.DeferRefresh())
                    {
                        // if shift is held down, we multi-sort, therefore if it isn't, we'll clear the sorts beforehand
                        if (!shift || owningGrid.DataConnection.SortDescriptions.Count == 0)
                        {
                            owningGrid.DataConnection.SortDescriptions.Clear();
                        }

                        // if ctrl is held down, we only clear the sort directions
                        if (!ctrl)
                        {
                            if (sort != null)
                            {
                                if (forcedDirection == null || sort.Direction != forcedDirection)
                                {
                                    newSort = sort.SwitchSortDirection();
                                }
                                else
                                {
                                    newSort = sort;
                                }

                                // changing direction should not affect sort order, so we replace this column's
                                // sort description instead of just adding it to the end of the collection
                                int oldIndex = owningGrid.DataConnection.SortDescriptions.IndexOf(sort);
                                if (oldIndex >= 0)
                                {
                                    owningGrid.DataConnection.SortDescriptions.Remove(sort);
                                    owningGrid.DataConnection.SortDescriptions.Insert(oldIndex, newSort);
                                }
                                else
                                {
                                    owningGrid.DataConnection.SortDescriptions.Add(newSort);
                                }
                            }
                            else if (OwningColumn.CustomSortComparer != null)
                            {
                                newSort = forcedDirection != null?
                                          DataGridSortDescription.FromComparer(OwningColumn.CustomSortComparer, forcedDirection.Value) :
                                              DataGridSortDescription.FromComparer(OwningColumn.CustomSortComparer);


                                owningGrid.DataConnection.SortDescriptions.Add(newSort);
                            }
                            else
                            {
                                string propertyName = OwningColumn.GetSortPropertyName();
                                // no-opt if we couldn't find a property to sort on
                                if (string.IsNullOrEmpty(propertyName))
                                {
                                    return;
                                }

                                newSort = DataGridSortDescription.FromPath(propertyName, culture: collectionView.Culture);
                                if (forcedDirection != null && newSort.Direction != forcedDirection)
                                {
                                    newSort = newSort.SwitchSortDirection();
                                }

                                owningGrid.DataConnection.SortDescriptions.Add(newSort);
                            }
                        }
                    }
                }
            }
        }
Example #18
0
        /// <summary>
        /// Builds the visual tree for the column header when a new template is applied.
        /// </summary>
        protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
        {
            RootElement = e.NameScope.Find <Panel>(DATAGRIDROW_elementRoot);
            if (RootElement != null)
            {
                EnsureBackground();
                UpdatePseudoClasses();
            }

            bool updateVerticalScrollBar = false;

            if (_cellsElement != null)
            {
                // If we're applying a new template, we  want to remove the cells from the previous _cellsElement
                _cellsElement.Children.Clear();
                updateVerticalScrollBar = true;
            }

            _cellsElement = e.NameScope.Find <DataGridCellsPresenter>(DATAGRIDROW_elementCells);
            if (_cellsElement != null)
            {
                _cellsElement.OwningRow = this;
                // Cells that were already added before the Template was applied need to
                // be added to the Canvas
                if (Cells.Count > 0)
                {
                    foreach (DataGridCell cell in Cells)
                    {
                        _cellsElement.Children.Add(cell);
                    }
                }
            }

            _detailsElement = e.NameScope.Find <DataGridDetailsPresenter>(DATAGRIDROW_elementDetails);
            if (_detailsElement != null && OwningGrid != null)
            {
                _detailsElement.OwningRow = this;
                if (ActualDetailsVisibility && ActualDetailsTemplate != null && _appliedDetailsTemplate == null)
                {
                    // Apply the DetailsTemplate now that the row template is applied.
                    SetDetailsVisibilityInternal(ActualDetailsVisibility, raiseNotification: _detailsVisibilityNotificationPending, animate: false);
                    _detailsVisibilityNotificationPending = false;
                }
            }

            _bottomGridLine = e.NameScope.Find <Rectangle>(DATAGRIDROW_elementBottomGridLine);
            EnsureGridLines();

            _headerElement = e.NameScope.Find <DataGridRowHeader>(DATAGRIDROW_elementRowHeader);
            if (_headerElement != null)
            {
                _headerElement.Owner = this;
                if (Header != null)
                {
                    _headerElement.Content = Header;
                }
                EnsureHeaderStyleAndVisibility(null);
            }

            //The height of this row might have changed after applying a new style, so fix the vertical scroll bar
            if (OwningGrid != null && updateVerticalScrollBar)
            {
                OwningGrid.UpdateVerticalScrollBar();
            }
        }
Example #19
0
        /// <summary>
        /// Measures the children of a <see cref="T:Avalonia.Controls.Primitives.DataGridCellsPresenter" /> to
        /// prepare for arranging them during the <see cref="M:System.Windows.FrameworkElement.ArrangeOverride(System.Windows.Size)" /> pass.
        /// </summary>
        /// <param name="availableSize">
        /// The available size that this element can give to child elements. Indicates an upper limit that child elements should not exceed.
        /// </param>
        /// <returns>
        /// The size that the <see cref="T:Avalonia.Controls.Primitives.DataGridCellsPresenter" /> determines it needs during layout, based on its calculations of child object allocated sizes.
        /// </returns>
        protected override Size MeasureOverride(Size availableSize)
        {
            if (OwningGrid == null)
            {
                return(base.MeasureOverride(availableSize));
            }

            bool   autoSizeHeight;
            double measureHeight;

            if (double.IsNaN(OwningGrid.RowHeight))
            {
                // No explicit height values were set so we can autosize
                autoSizeHeight = true;
                measureHeight  = double.PositiveInfinity;
            }
            else
            {
                DesiredHeight  = OwningGrid.RowHeight;
                measureHeight  = DesiredHeight;
                autoSizeHeight = false;
            }

            double frozenLeftEdge    = 0;
            double totalDisplayWidth = 0;
            double scrollingLeftEdge = -OwningGrid.HorizontalOffset;

            OwningGrid.ColumnsInternal.EnsureVisibleEdgedColumnsWidth();
            DataGridColumn lastVisibleColumn = OwningGrid.ColumnsInternal.LastVisibleColumn;

            foreach (DataGridColumn column in OwningGrid.ColumnsInternal.GetVisibleColumns())
            {
                DataGridCell cell = OwningRow.Cells[column.Index];
                // Measure the entire first row to make the horizontal scrollbar more accurate
                bool shouldDisplayCell = ShouldDisplayCell(column, frozenLeftEdge, scrollingLeftEdge) || OwningRow.Index == 0;
                EnsureCellDisplay(cell, shouldDisplayCell);
                if (shouldDisplayCell)
                {
                    DataGridLength columnWidth   = column.Width;
                    bool           autoGrowWidth = columnWidth.IsSizeToCells || columnWidth.IsAuto;
                    if (column != lastVisibleColumn)
                    {
                        cell.EnsureGridLine(lastVisibleColumn);
                    }

                    // If we're not using star sizing or the current column can't be resized,
                    // then just set the display width according to the column's desired width
                    if (!OwningGrid.UsesStarSizing || (!column.ActualCanUserResize && !column.Width.IsStar))
                    {
                        // In the edge-case where we're given infinite width and we have star columns, the
                        // star columns grow to their predefined limit of 10,000 (or their MaxWidth)
                        double newDisplayWidth = column.Width.IsStar ?
                                                 Math.Min(column.ActualMaxWidth, DataGrid.DATAGRID_maximumStarColumnWidth) :
                                                 Math.Max(column.ActualMinWidth, Math.Min(column.ActualMaxWidth, column.Width.DesiredValue));
                        column.SetWidthDisplayValue(newDisplayWidth);
                    }

                    // If we're auto-growing the column based on the cell content, we want to measure it at its maximum value
                    if (autoGrowWidth)
                    {
                        cell.Measure(new Size(column.ActualMaxWidth, measureHeight));
                        OwningGrid.AutoSizeColumn(column, cell.DesiredSize.Width);
                        column.ComputeLayoutRoundedWidth(totalDisplayWidth);
                    }
                    else if (!OwningGrid.UsesStarSizing)
                    {
                        column.ComputeLayoutRoundedWidth(scrollingLeftEdge);
                        cell.Measure(new Size(column.LayoutRoundedWidth, measureHeight));
                    }

                    // We need to track the largest height in order to auto-size
                    if (autoSizeHeight)
                    {
                        DesiredHeight = Math.Max(DesiredHeight, cell.DesiredSize.Height);
                    }
                }

                if (column.IsFrozen)
                {
                    frozenLeftEdge += column.ActualWidth;
                }
                scrollingLeftEdge += column.ActualWidth;
                totalDisplayWidth += column.ActualWidth;
            }

            // If we're using star sizing (and we're not waiting for an auto-column to finish growing)
            // then we will resize all the columns to fit the available space.
            if (OwningGrid.UsesStarSizing && !OwningGrid.AutoSizingColumns)
            {
                double adjustment = OwningGrid.CellsWidth - totalDisplayWidth;
                totalDisplayWidth += adjustment - OwningGrid.AdjustColumnWidths(0, adjustment, false);

                // Since we didn't know the final widths of the columns until we resized,
                // we waited until now to measure each cell
                double leftEdge = 0;
                if (autoSizeHeight)
                {
                    DesiredHeight = 0;
                }

                foreach (DataGridColumn column in OwningGrid.ColumnsInternal.GetVisibleColumns())
                {
                    DataGridCell cell = OwningRow.Cells[column.Index];
                    column.ComputeLayoutRoundedWidth(leftEdge);
                    cell.Measure(new Size(column.LayoutRoundedWidth, measureHeight));
                    if (autoSizeHeight)
                    {
                        DesiredHeight = Math.Max(DesiredHeight, cell.DesiredSize.Height);
                    }
                    leftEdge += column.ActualWidth;
                }
            }

            // Measure FillerCell, we're doing it unconditionally here because we don't know if we'll need the filler
            // column and we don't want to cause another Measure if we do
            OwningRow.FillerCell.Measure(new Size(double.PositiveInfinity, DesiredHeight));

            OwningGrid.ColumnsInternal.EnsureVisibleEdgedColumnsWidth();
            return(new Size(OwningGrid.ColumnsInternal.VisibleEdgedColumnsWidth, DesiredHeight));
        }
Example #20
0
        internal void ApplyDetailsTemplate(bool initializeDetailsPreferredHeight)
        {
            if (_detailsElement != null && AreDetailsVisible)
            {
                IDataTemplate oldDetailsTemplate = _appliedDetailsTemplate;
                if (ActualDetailsTemplate != null && ActualDetailsTemplate != _appliedDetailsTemplate)
                {
                    if (_detailsContent != null)
                    {
                        _detailsContentSizeSubscription?.Dispose();
                        _detailsContentSizeSubscription = null;
                        if (_detailsLoaded)
                        {
                            OwningGrid.OnUnloadingRowDetails(this, _detailsContent);
                            _detailsLoaded = false;
                        }
                    }
                    _detailsElement.Children.Clear();

                    _detailsContent         = ActualDetailsTemplate.Build(DataContext);
                    _appliedDetailsTemplate = ActualDetailsTemplate;

                    if (_detailsContent != null)
                    {
                        if (_detailsContent is Layout.Layoutable layoutableContent)
                        {
                            layoutableContent.LayoutUpdated += DetailsContent_LayoutUpdated;

                            _detailsContentSizeSubscription =
                                System.Reactive.Disposables.StableCompositeDisposable.Create(
                                    System.Reactive.Disposables.Disposable.Create(() => layoutableContent.LayoutUpdated -= DetailsContent_LayoutUpdated),
                                    _detailsContent.GetObservable(MarginProperty)
                                    .Subscribe(DetailsContent_MarginChanged));
                        }
                        else
                        {
                            _detailsContentSizeSubscription =
                                _detailsContent.GetObservable(MarginProperty)
                                .Subscribe(DetailsContent_MarginChanged);
                        }

                        _detailsElement.Children.Add(_detailsContent);
                    }
                }

                if (_detailsContent != null && !_detailsLoaded)
                {
                    _detailsLoaded = true;
                    _detailsContent.DataContext = DataContext;
                    OwningGrid.OnLoadingRowDetails(this, _detailsContent);
                }
                if (initializeDetailsPreferredHeight && double.IsNaN(_detailsDesiredHeight) &&
                    _appliedDetailsTemplate != null && _detailsElement.Children.Count > 0)
                {
                    EnsureDetailsDesiredHeight();
                }
                else if (oldDetailsTemplate == null)
                {
                    _detailsDesiredHeight = double.NaN;
                    EnsureDetailsDesiredHeight();
                    _detailsElement.ContentHeight = _detailsDesiredHeight;
                }
            }
        }