private static object OnCoerceHeaderStyle(DependencyObject d, object baseValue) { var row = (DataGridRow)d; return(DataGridHelper.GetCoercedTransferPropertyValue( row, baseValue, HeaderStyleProperty, row.DataGridOwner, DataGrid.RowHeaderStyleProperty)); }
private static object OnCoerceValidationErrorTemplate(DependencyObject d, object baseValue) { var row = (DataGridRow)d; return(DataGridHelper.GetCoercedTransferPropertyValue( row, baseValue, ValidationErrorTemplateProperty, row.DataGridOwner, DataGrid.RowValidationErrorTemplateProperty)); }
/// <summary> /// Called when a cell's value is to be cancelled, just before it exits edit mode. /// </summary> /// <param name="editingElement">A reference to element returned by GenerateEditingElement.</param> /// <param name="uneditedValue">UneditedValue</param> protected override void CancelCellEdit(FrameworkElement editingElement, object uneditedValue) { ComboBox comboBox = editingElement as ComboBox; if (comboBox != null) { DataGridHelper.UpdateTarget(comboBox, ComboBox.SelectedValueProperty); DataGridHelper.UpdateTarget(comboBox, ComboBox.SelectedItemProperty); DataGridHelper.UpdateTarget(comboBox, ComboBox.TextProperty); } }
private static object OnCoerceDetailsTemplateSelector(DependencyObject d, object baseValue) { var row = (DataGridRow)d; return(DataGridHelper.GetCoercedTransferPropertyValue( row, baseValue, DetailsTemplateSelectorProperty, row.DataGridOwner, DataGrid.RowDetailsTemplateSelectorProperty)); }
/// <summary> /// Called when a cell's value is to be committed, just before it exits edit mode. /// </summary> /// <param name="editingElement">A reference to element returned by GenerateEditingElement.</param> /// <returns>false if there is a validation error. true otherwise.</returns> protected override bool CommitCellEdit(FrameworkElement editingElement) { TextBox textBox = editingElement as TextBox; if (textBox != null) { DataGridHelper.UpdateSource(textBox, TextBox.TextProperty); return(!Validation.GetHasError(textBox)); } return(true); }
/// <summary> /// Called when a cell's value is to be committed, just before it exits edit mode. /// </summary> /// <param name="editingElement">A reference to element returned by GenerateEditingElement.</param> /// <returns>false if there is a validation error. true otherwise.</returns> protected override bool CommitCellEdit(FrameworkElement editingElement) { CheckBox checkBox = editingElement as CheckBox; if (checkBox != null) { DataGridHelper.UpdateSource(checkBox, CheckBox.IsCheckedProperty); return(!Validation.GetHasError(checkBox)); } return(true); }
private static object OnCoerceSortMemberPath(DependencyObject d, object baseValue) { var column = (DataGridComboBoxColumn)d; var sortMemberPath = (string)baseValue; if (string.IsNullOrEmpty(sortMemberPath)) { sortMemberPath = DataGridHelper.GetPathFromBinding(column.EffectiveBinding as Binding); } return(sortMemberPath); }
protected internal override void RefreshCellContent(FrameworkElement element, string propertyName) { DataGridCell cell = element as DataGridCell; if (cell != null) { bool isCellEditing = cell.IsEditing; if ((string.Compare(propertyName, "ElementStyle", StringComparison.Ordinal) == 0 && !isCellEditing) || (string.Compare(propertyName, "EditingElementStyle", StringComparison.Ordinal) == 0 && isCellEditing)) { cell.BuildVisualTree(); } else { ComboBox comboBox = cell.Content as ComboBox; switch (propertyName) { case "SelectedItemBinding": ApplyBinding(SelectedItemBinding, comboBox, ComboBox.SelectedItemProperty); break; case "SelectedValueBinding": ApplyBinding(SelectedValueBinding, comboBox, ComboBox.SelectedValueProperty); break; case "TextBinding": ApplyBinding(TextBinding, comboBox, ComboBox.TextProperty); break; case "SelectedValuePath": DataGridHelper.SyncColumnProperty(this, comboBox, ComboBox.SelectedValuePathProperty, SelectedValuePathProperty); break; case "DisplayMemberPath": DataGridHelper.SyncColumnProperty(this, comboBox, ComboBox.DisplayMemberPathProperty, DisplayMemberPathProperty); break; case "ItemsSource": DataGridHelper.SyncColumnProperty(this, comboBox, ComboBox.ItemsSourceProperty, ItemsSourceProperty); break; default: base.RefreshCellContent(element, propertyName); break; } } } else { base.RefreshCellContent(element, propertyName); } }
private static void OnAnyGotFocus(object sender, RoutedEventArgs e) { DataGridCell cell = DataGridHelper.FindVisualParent <DataGridCell>(e.OriginalSource as UIElement); if (cell != null && cell == sender) { DataGrid owner = cell.DataGridOwner; if (owner != null) { owner.FocusedCell = cell; } } }
private static object OnCoerceStyle(DependencyObject d, object baseValue) { var cell = d as DataGridCell; return(DataGridHelper.GetCoercedTransferPropertyValue( cell, baseValue, StyleProperty, cell.Column, DataGridColumn.CellStyleProperty, cell.DataGridOwner, DataGrid.CellStyleProperty)); }
/// <summary> /// OnRender. Overriden to draw a vertical line on the right. /// </summary> /// <param name="drawingContext"></param> protected override void OnRender(DrawingContext drawingContext) { base.OnRender(drawingContext); if (DataGridHelper.IsGridLineVisible(DataGridOwner, /*isHorizontal = */ false)) { double thickness = DataGridOwner.VerticalGridLineThickness; Rect rect = new Rect(new Size(thickness, RenderSize.Height)); rect.X = RenderSize.Width - thickness; drawingContext.DrawRectangle(DataGridOwner.VerticalGridLinesBrush, null, rect); } }
/// <summary> /// Called when a cell's value is to be committed, just before it exits edit mode. /// </summary> /// <param name="editingElement">A reference to element returned by GenerateEditingElement.</param> /// <returns>false if there is a validation error. true otherwise.</returns> protected override bool CommitCellEdit(FrameworkElement editingElement) { ComboBox comboBox = editingElement as ComboBox; if (comboBox != null) { DataGridHelper.UpdateSource(comboBox, ComboBox.SelectedValueProperty); DataGridHelper.UpdateSource(comboBox, ComboBox.SelectedItemProperty); DataGridHelper.UpdateSource(comboBox, ComboBox.TextProperty); return(!Validation.GetHasError(comboBox)); } return(true); }
private static object OnCoerceIsReadOnly(DependencyObject d, object baseValue) { var cell = d as DataGridCell; var column = cell.Column; var dataGrid = cell.DataGridOwner; // We dont use the cell & 'baseValue' here because this property is read only on cell. // the column may coerce a default value to 'true', so we'll use it's effective value for IsReadOnly // as the baseValue. return(DataGridHelper.GetCoercedTransferPropertyValue( column, column.IsReadOnly, DataGridColumn.IsReadOnlyProperty, dataGrid, DataGrid.IsReadOnlyProperty)); }
private static void OnAnyLostFocus(object sender, RoutedEventArgs e) { // Get the ancestor cell of old focused element. // Set DataGrid.FocusedCell to null, if the cell doesn't // have keyboard focus. DataGridCell cell = DataGridHelper.FindVisualParent <DataGridCell>(e.OriginalSource as UIElement); if (cell != null && cell == sender) { DataGrid owner = cell.DataGridOwner; if (owner != null && !cell.IsKeyboardFocusWithin && owner.FocusedCell == cell) { owner.FocusedCell = null; } } }
/// <summary> /// Arrange. This is overriden so that the cell can position its content to account for a grid line on the right. /// </summary> /// <param name="arrangeSize">Arrange size</param> protected override Size ArrangeOverride(Size arrangeSize) { // We don't need to adjust the Arrange position of the content. By default it is arranged at 0,0 and we're // adding a line to the right. All we have to do is compress and extend the size, just like Measure. if (DataGridHelper.IsGridLineVisible(DataGridOwner, /*isHorizontal = */ false)) { double thickness = DataGridOwner.VerticalGridLineThickness; Size returnSize = base.ArrangeOverride(DataGridHelper.SubtractFromSize(arrangeSize, thickness, /*height = */ false)); returnSize.Width += thickness; return(returnSize); } else { return(base.ArrangeOverride(arrangeSize)); } }
/// <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); } } } }
// Different parts of the DataGrid draw different pieces of the GridLines. // Cells draw a single line on their right side. /// <summary> /// Measure. This is overridden so that the cell can extend its size to account for a grid line on the right. /// </summary> protected override Size MeasureOverride(Size constraint) { // Make space for the GridLine on the right: // Remove space from the constraint (since it implicitly includes the GridLine's thickness), // call the base implementation, and add the thickness back for the returned size. if (DataGridHelper.IsGridLineVisible(DataGridOwner, /*isHorizontal = */ false)) { double thickness = DataGridOwner.VerticalGridLineThickness; Size desiredSize = base.MeasureOverride(DataGridHelper.SubtractFromSize(constraint, thickness, /*height = */ false)); desiredSize.Width += thickness; return(desiredSize); } else { return(base.MeasureOverride(constraint)); } }
/// <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; } 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); }
/// <summary> /// Coercion call back for clip property which ensures that the cell overlapping with frozen /// column gets clipped appropriately. /// </summary> /// <param name="d"></param> /// <param name="baseValue"></param> /// <returns></returns> private static object OnCoerceClip(DependencyObject d, object baseValue) { DataGridCell cell = (DataGridCell)d; Geometry geometry = baseValue as Geometry; Geometry frozenGeometry = DataGridHelper.GetFrozenClipForCell(cell); if (frozenGeometry != null) { if (geometry == null) { return(frozenGeometry); } geometry = new CombinedGeometry(GeometryCombineMode.Intersect, geometry, frozenGeometry); } return(geometry); }
protected internal override void RefreshCellContent(FrameworkElement element, string propertyName) { DataGridCell cell = element as DataGridCell; if (cell != null) { FrameworkElement textElement = cell.Content as FrameworkElement; if (textElement != null) { switch (propertyName) { case "FontFamily": DataGridHelper.SyncColumnProperty(this, textElement, TextElement.FontFamilyProperty, FontFamilyProperty); break; case "FontSize": DataGridHelper.SyncColumnProperty(this, textElement, TextElement.FontSizeProperty, FontSizeProperty); break; case "FontStyle": DataGridHelper.SyncColumnProperty(this, textElement, TextElement.FontStyleProperty, FontStyleProperty); break; case "FontWeight": DataGridHelper.SyncColumnProperty(this, textElement, TextElement.FontWeightProperty, FontWeightProperty); break; case "Foreground": DataGridHelper.SyncColumnProperty(this, textElement, TextElement.ForegroundProperty, ForegroundProperty); break; } } } base.RefreshCellContent(element, propertyName); }
private static object OnCoerceDetailsVisibility(DependencyObject d, object baseValue) { var row = (DataGridRow)d; object visibility = DataGridHelper.GetCoercedTransferPropertyValue( row, baseValue, DetailsVisibilityProperty, row.DataGridOwner, DataGrid.RowDetailsVisibilityModeProperty); if (visibility is DataGridRowDetailsVisibilityMode) { var visibilityMode = (DataGridRowDetailsVisibilityMode)visibility; var hasDetailsTemplate = row.DetailsTemplate != null || row.DetailsTemplateSelector != null; var isRealItem = row.Item != CollectionView.NewItemPlaceholder; switch (visibilityMode) { case DataGridRowDetailsVisibilityMode.Collapsed: visibility = Visibility.Collapsed; break; case DataGridRowDetailsVisibilityMode.Visible: visibility = hasDetailsTemplate && isRealItem ? Visibility.Visible : Visibility.Collapsed; break; case DataGridRowDetailsVisibilityMode.VisibleWhenSelected: visibility = row.IsSelected && hasDetailsTemplate && isRealItem ? Visibility.Visible : Visibility.Collapsed; break; default: visibility = Visibility.Collapsed; break; } } return(visibility); }
/// <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); } }
/// <summary> /// Searchs up the visual parent chain from the given element until /// a DataGridRow element is found. /// </summary> /// <param name="element">The descendent of a DataGridRow.</param> /// <returns> /// The first ancestor DataGridRow of the element parameter. /// Returns null of none is found. /// </returns> public static DataGridRow GetRowContainingElement(FrameworkElement element) { return(DataGridHelper.FindVisualParent <DataGridRow>(element)); }