/// <summary>
 ///     Called due to the cell's column definition changing.
 ///     Not called due to changes within the current column definition.
 /// </summary>
 /// <remarks>
 ///     Coerces ContentTemplate and ContentTemplateSelector.
 /// </remarks>
 /// <param name="oldColumn">The old column definition.</param>
 /// <param name="newColumn">The new column definition.</param>
 protected virtual void OnColumnChanged(DataGridColumn oldColumn, DataGridColumn newColumn)
 {
     // We need to call BuildVisualTree after changing the column (PrepareCell does this).
     Content = null;
     DataGridHelper.TransferProperty(this, StyleProperty);
     DataGridHelper.TransferProperty(this, IsReadOnlyProperty);
 }
Beispiel #2
0
        /// <summary>
        ///     Fired when the Row is attached to the DataGrid.  The scenario here is if the user is scrolling and
        ///     the Row is a recycled container that was just added back to the visual tree.  Properties that rely on a value from
        ///     the Grid should be reevaluated because they may be stale.
        /// </summary>
        /// <remarks>
        ///     Properties can obviously be stale if the DataGrid's value changes while the row is disconnected.  They can also
        ///     be stale for unobvious reasons.
        ///
        ///     For example, the Style property is invalidated when we detect a new Visual parent.  This happens for
        ///     elements in the row (such as the RowHeader) before Prepare is called on the Row.  The coercion callback
        ///     will thus be unable to find the DataGrid and will return the wrong value.
        ///
        ///     There is a potential for perf work here.  If we know a DP isn't invalidated when the visual tree is reconnected
        ///     and we know that the Grid hasn't modified that property then its value is likely fine.  We could also cache whether
        ///     or not the Grid's property is the one that's winning.  If not, no need to redo the coercion.  This notification
        ///     is pretty fast already and thus not worth the work for now.
        /// </remarks>
        private void SyncProperties(bool forcePrepareCells)
        {
            // Coerce all properties on Row that depend on values from the DataGrid
            // Style is ok since it's equivalent to ItemContainerStyle and has already been invalidated.
            DataGridHelper.TransferProperty(this, BackgroundProperty);
            DataGridHelper.TransferProperty(this, HeaderStyleProperty);
            DataGridHelper.TransferProperty(this, HeaderTemplateProperty);
            DataGridHelper.TransferProperty(this, HeaderTemplateSelectorProperty);
            DataGridHelper.TransferProperty(this, ValidationErrorTemplateProperty);
            DataGridHelper.TransferProperty(this, DetailsTemplateProperty);
            DataGridHelper.TransferProperty(this, DetailsTemplateSelectorProperty);
            DataGridHelper.TransferProperty(this, DetailsVisibilityProperty);

            CoerceValue(VisibilityProperty); // Handle NewItemPlaceholder case

            RestoreAttachedItemValue(this, DetailsVisibilityProperty);

            var cellsPresenter = CellsPresenter;

            if (cellsPresenter != null)
            {
                cellsPresenter.SyncProperties(forcePrepareCells);
                RestoreAttachedItemValue(cellsPresenter, DataGridCellsPresenter.HeightProperty);
            }

            if (DetailsPresenter != null)
            {
                DetailsPresenter.SyncProperties();
            }

            if (RowHeader != null)
            {
                RowHeader.SyncProperties();
            }
        }
        /// <summary>
        ///     General notification for DependencyProperty changes from the grid or from columns.
        /// </summary>
        internal void NotifyPropertyChanged(DependencyObject d, string propertyName, DependencyPropertyChangedEventArgs e, NotificationTarget target)
        {
            DataGridColumn column = d as DataGridColumn;

            if ((column != null) && (column != Column))
            {
                // This notification does not apply to this cell
                return;
            }

            // All the notifications which are to be handled by the cell
            if (DataGridHelper.ShouldNotifyCells(target))
            {
                if (e.Property == DataGridColumn.WidthProperty)
                {
                    DataGridHelper.OnColumnWidthChanged(this, e);
                }
                else if (e.Property == DataGrid.CellStyleProperty || e.Property == DataGridColumn.CellStyleProperty || e.Property == StyleProperty)
                {
                    DataGridHelper.TransferProperty(this, StyleProperty);
                }
                else if (e.Property == DataGrid.IsReadOnlyProperty || e.Property == DataGridColumn.IsReadOnlyProperty || e.Property == IsReadOnlyProperty)
                {
                    DataGridHelper.TransferProperty(this, IsReadOnlyProperty);
                }
                else if (e.Property == DataGridColumn.DisplayIndexProperty)
                {
                    TabIndex = column.DisplayIndex;
                }
            }

            // All the notifications which needs forward to columns
            if (DataGridHelper.ShouldRefreshCellContent(target))
            {
                if (column != null && NeedsVisualTree)
                {
                    if (!string.IsNullOrEmpty(propertyName))
                    {
                        column.RefreshCellContent(this, propertyName);
                    }
                    else if (e != null && e.Property != null)
                    {
                        column.RefreshCellContent(this, e.Property.Name);
                    }
                }
            }
        }
Beispiel #4
0
        /// <summary>
        ///     Prepares a cell for use.
        /// </summary>
        /// <remarks>
        ///     Updates the column reference.
        /// </remarks>
        internal void PrepareCell(object item, DataGridRow ownerRow, int index)
        {
            Debug.Assert(_owner == null || _owner == ownerRow, "_owner should be null before PrepareCell is called or the same value as the ownerRow.");

            _owner = ownerRow;

            DataGrid dataGrid = _owner.DataGridOwner;

            if (dataGrid != null)
            {
                // The index of the container should correspond to the index of the column
                if ((index >= 0) && (index < dataGrid.Columns.Count))
                {
                    // Retrieve the column definition and pass it to the cell container
                    DataGridColumn column = dataGrid.Columns[index];
                    Column    = column;
                    TabIndex  = column.DisplayIndex;
                    IsTabStop = !column.DisableTab;
                }

                if (IsEditing)
                {
                    // If IsEditing was left on and this container was recycled, reset it here.
                    // Setting this property will result in BuildVisualTree being called.
                    IsEditing = false;
                }
                else if ((Content as FrameworkElement) == null)
                {
                    // If there isn't already a visual tree, then create one.
                    BuildVisualTree();

                    if (!NeedsVisualTree)
                    {
                        Content = item;
                    }
                }

                // Update cell Selection
                bool isSelected = dataGrid.SelectedCellsInternal.Contains(this);
                SyncIsSelected(isSelected);
            }

            DataGridHelper.TransferProperty(this, StyleProperty);
            DataGridHelper.TransferProperty(this, IsReadOnlyProperty);
            CoerceValue(ClipProperty);
        }
Beispiel #5
0
        /// <summary>
        ///     General notification for DependencyProperty changes from the grid or from columns.
        /// </summary>
        internal void NotifyPropertyChanged(DependencyObject d, string propertyName, DependencyPropertyChangedEventArgs e, NotificationTarget target)
        {
            if (DataGridHelper.ShouldNotifyRows(target))
            {
                if (e.Property == DataGrid.RowBackgroundProperty || e.Property == DataGrid.AlternatingRowBackgroundProperty ||
                    e.Property == BackgroundProperty || e.Property == AlternationIndexProperty)
                {
                    DataGridHelper.TransferProperty(this, BackgroundProperty);
                }
                else if (e.Property == DataGrid.RowHeaderStyleProperty || e.Property == HeaderStyleProperty)
                {
                    DataGridHelper.TransferProperty(this, HeaderStyleProperty);
                }
                else if (e.Property == DataGrid.RowHeaderTemplateProperty || e.Property == HeaderTemplateProperty)
                {
                    DataGridHelper.TransferProperty(this, HeaderTemplateProperty);
                }
                else if (e.Property == DataGrid.RowHeaderTemplateSelectorProperty || e.Property == HeaderTemplateSelectorProperty)
                {
                    DataGridHelper.TransferProperty(this, HeaderTemplateSelectorProperty);
                }
                else if (e.Property == DataGrid.RowValidationErrorTemplateProperty || e.Property == ValidationErrorTemplateProperty)
                {
                    DataGridHelper.TransferProperty(this, ValidationErrorTemplateProperty);
                }
                else if (e.Property == DataGrid.RowDetailsTemplateProperty || e.Property == DetailsTemplateProperty)
                {
                    DataGridHelper.TransferProperty(this, DetailsTemplateProperty);
                    DataGridHelper.TransferProperty(this, DetailsVisibilityProperty);
                }
                else if (e.Property == DataGrid.RowDetailsTemplateSelectorProperty || e.Property == DetailsTemplateSelectorProperty)
                {
                    DataGridHelper.TransferProperty(this, DetailsTemplateSelectorProperty);
                    DataGridHelper.TransferProperty(this, DetailsVisibilityProperty);
                }
                else if (e.Property == DataGrid.RowDetailsVisibilityModeProperty || e.Property == DetailsVisibilityProperty || e.Property == IsSelectedProperty)
                {
                    DataGridHelper.TransferProperty(this, DetailsVisibilityProperty);
                }
                else if (e.Property == ItemProperty)
                {
                    OnItemChanged(e.OldValue, e.NewValue);
                }
                else if (e.Property == HeaderProperty)
                {
                    OnHeaderChanged(e.OldValue, e.NewValue);
                }
                else if (e.Property == BindingGroupProperty)
                {
                    // Re-run validation, but wait until Binding has occured.
                    Dispatcher.BeginInvoke(new DispatcherOperationCallback(DelayedValidateWithoutUpdate), DispatcherPriority.DataBind, e.NewValue);
                }
            }

            if (DataGridHelper.ShouldNotifyDetailsPresenter(target))
            {
                if (DetailsPresenter != null)
                {
                    DetailsPresenter.NotifyPropertyChanged(d, e);
                }
            }

            if (DataGridHelper.ShouldNotifyCellsPresenter(target) ||
                DataGridHelper.ShouldNotifyCells(target) ||
                DataGridHelper.ShouldRefreshCellContent(target))
            {
                DataGridCellsPresenter cellsPresenter = CellsPresenter;
                if (cellsPresenter != null)
                {
                    cellsPresenter.NotifyPropertyChanged(d, propertyName, e, target);
                }
            }

            if (DataGridHelper.ShouldNotifyRowHeaders(target) && RowHeader != null)
            {
                RowHeader.NotifyPropertyChanged(d, e);
            }
        }