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; } }
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; } } }
//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; } }
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; } }
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); } } } }
//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*/); }
//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); } }
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); } } } } } }
/// <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(); } }
/// <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)); }
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; } } }