/// <summary> /// SelectedItemProperty property changed handler. /// </summary> /// <param name="d">DataGrid that changed its SelectedItem.</param> /// <param name="e">DependencyPropertyChangedEventArgs.</param> private static void OnSelectedItemPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { DataGrid dataGrid = (DataGrid)d; if (!dataGrid.AreHandlersSuspended()) { int rowIndex = (e.NewValue == null) ? -1 : dataGrid.DataConnection.IndexOf(e.NewValue); if (rowIndex == -1) { // If the Item is null or it's not found, clear the Selection if (!dataGrid.CommitEdit(DataGridEditingUnit.Row, true /*exitEditing*/)) { // Edited value couldn't be committed or aborted d.SetValueNoCallback(e.Property, e.OldValue); return; } // Clear all row selections dataGrid.ClearRowSelection(true /*resetAnchorSlot*/); } else { int slot = dataGrid.SlotFromRowIndex(rowIndex); if (slot != dataGrid.CurrentSlot) { if (!dataGrid.CommitEdit(DataGridEditingUnit.Row, true /*exitEditing*/)) { // Edited value couldn't be committed or aborted d.SetValueNoCallback(e.Property, e.OldValue); return; } if (slot >= dataGrid.SlotCount || slot < -1) { if (dataGrid.DataConnection.CollectionView != null) { dataGrid.DataConnection.CollectionView.MoveCurrentToPosition(rowIndex); } } } int oldSelectedIndex = dataGrid.SelectedIndex; dataGrid.SetValueNoCallback(DataGrid.SelectedIndexProperty, rowIndex); try { dataGrid._noSelectionChangeCount++; int columnIndex = dataGrid.CurrentColumnIndex; if (columnIndex == -1) { columnIndex = dataGrid.FirstDisplayedNonFillerColumnIndex; } if (dataGrid.IsSlotOutOfSelectionBounds(slot)) { dataGrid.ClearRowSelection(slot /*slotException*/, true /*resetAnchorSlot*/); return; } dataGrid.UpdateSelectionAndCurrency(columnIndex, slot, DataGridSelectionAction.SelectCurrent, false /*scrollIntoView*/); } finally { dataGrid.NoSelectionChangeCount--; } if (!dataGrid._successfullyUpdatedSelection) { dataGrid.SetValueNoCallback(DataGrid.SelectedIndexProperty, oldSelectedIndex); d.SetValueNoCallback(e.Property, e.OldValue); } } } }
/// <summary> /// IsReadOnlyProperty property changed handler. /// </summary> /// <param name="d">DataGrid that changed its IsReadOnly.</param> /// <param name="e">DependencyPropertyChangedEventArgs.</param> private static void OnIsReadOnlyPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { DataGrid source = d as DataGrid; Debug.Assert(source != null, "The source is not an instance of DataGrid!"); Debug.Assert(typeof(bool).IsInstanceOfType(e.NewValue), "The value is not an instance of bool!"); bool value = (bool)e.NewValue; if (!source.IsHandlerSuspended(e.Property)) { if (value && !source.EndEdit(true /*commitChanges*/, true /*exitEditingMode*/)) { d.SetValueNoCallback(e.Property, e.OldValue); throw DataGridError.DataGrid.CommitFailedCannotCompleteOperation(); } } }
/// <summary> /// SelectedIndexProperty property changed handler. /// </summary> /// <param name="d">DataGrid that changed its SelectedIndex.</param> /// <param name="e">DependencyPropertyChangedEventArgs.</param> private static void OnSelectedIndexPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { DataGrid dataGrid = (DataGrid)d; if (!dataGrid.AreHandlersSuspended()) { int index = (int)e.NewValue; // GetDataItem returns null if index is >= Count, we do not check newValue // against Count here to avoid enumerating through an Enumerable twice // Setting SelectedItem coerces the finally value of the SelectedIndex object newSelectedItem = (index < 0) ? null : dataGrid.DataConnection.GetDataItem(index); dataGrid.SelectedItem = newSelectedItem; if (dataGrid.SelectedItem != newSelectedItem) { d.SetValueNoCallback(e.Property, e.OldValue); } } }
/// <summary> /// ColumnHeadersHeightProperty property changed handler. /// </summary> /// <param name="d">DataGrid that changed its ColumnHeadersHeight.</param> /// <param name="e">DependencyPropertyChangedEventArgs.</param> private static void OnColumnHeadersHeightPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { DataGrid source = d as DataGrid; Debug.Assert(source != null, "The source is not an instance of DataGrid!"); Debug.Assert(typeof(double).IsInstanceOfType(e.NewValue), "The value is not an instance of double!"); double value = (double)e.NewValue; if (!source.IsHandlerSuspended(e.Property)) { if (value < DATAGRID_minimumColumnHeadersHeight) { d.SetValueNoCallback(e.Property, e.OldValue); throw DataGridError.DataGrid.ValueMustBeGreaterThanOrEqualTo("value", "ColumnHeadersHeight", DATAGRID_minimumColumnHeadersHeight); } if (value > DATAGRID_maxHeadersThickness) { d.SetValueNoCallback(e.Property, e.OldValue); throw DataGridError.DataGrid.ValueMustBeLessThanOrEqualTo("value", "ColumnHeadersHeight", DATAGRID_maxHeadersThickness); } source.PerformLayout(); } }
/// <summary> /// ColumnWidthProperty property changed handler. /// </summary> /// <param name="d">DataGrid that changed its ColumnWidth.</param> /// <param name="e">DependencyPropertyChangedEventArgs.</param> private static void OnColumnWidthPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { DataGrid source = d as DataGrid; Debug.Assert(source != null, "The source is not an instance of DataGrid!"); Debug.Assert(typeof(double).IsInstanceOfType(e.NewValue), "The value is not an instance of double!"); double value = (double)e.NewValue; if (!source.IsHandlerSuspended(e.Property)) { // coerce value if (value < source.MinColumnWidth) { source.SetValueNoCallback(ColumnWidthProperty, source.MinColumnWidth); } if (value > DataGridColumnBase.DATAGRIDCOLUMN_maximumWidth) { d.SetValueNoCallback(e.Property, e.OldValue); throw DataGridError.DataGrid.ValueMustBeLessThanOrEqualTo("value", "ColumnWidth", DataGridColumnBase.DATAGRIDCOLUMN_maximumWidth); } // validated against inherited value if appropriate bool inheritingGridColumnWidth = false; foreach (DataGridColumnBase dataGridColumn in source.ColumnsItemsInternal) { if (dataGridColumn.LocalWidth == 0) { inheritingGridColumnWidth = true; if (value < dataGridColumn.InheritedMinWidth) { d.SetValueNoCallback(e.Property, e.OldValue); throw DataGridError.DataGrid.ValueMustBeGreaterThanOrEqualTo("value", "ColumnWidth", dataGridColumn.InheritedMinWidth); // } } } if (inheritingGridColumnWidth) { // The inherited ColumnWidth has changed so layout needs to be updated source.PerformLayout(); } } }
/// <summary> /// SelectedItemsProperty property changed handler. /// </summary> /// <param name="d">DataGrid that changed its SelectedItems.</param> /// <param name="e">DependencyPropertyChangedEventArgs.</param> private static void OnSelectedItemsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { DataGrid source = d as DataGrid; Debug.Assert(source != null, "The source is not an instance of DataGrid!"); if (!typeof(DataGridSelectedItemsCollection).IsInstanceOfType(e.NewValue) || (e.NewValue == null)) { d.SetValueNoCallback(e.Property, e.OldValue); throw DataGridError.DataGrid.ValueIsNotAnInstanceOf("value", typeof(DataGridSelectedItemsCollection)); } else if (e.OldValue != null || source != ((DataGridSelectedItemsCollection)e.NewValue).OwningGrid) { d.SetValueNoCallback(e.Property, e.OldValue); throw DataGridError.DataGrid.ValueIsReadOnly("SelectedItems"); } }
/// <summary> /// SelectedItemProperty property changed handler. /// </summary> /// <param name="d">DataGrid that changed its SelectedItem.</param> /// <param name="e">DependencyPropertyChangedEventArgs.</param> private static void OnSelectedItemPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { DataGrid source = d as DataGrid; Debug.Assert(source != null, "The source is not an instance of DataGrid!"); Debug.Assert(typeof(object).IsInstanceOfType(e.NewValue) || (e.NewValue == null), "The value is not an instance of object!"); if (!source.IsHandlerSuspended(e.Property)) { if (e.NewValue == null) { if (!source.EndEdit(true /*commitChanges*/, true /*exitEditingMode*/)) { // Edited value couldn't be committed or aborted d.SetValueNoCallback(e.Property, e.OldValue); throw DataGridError.DataGrid.CommitFailedCannotCompleteOperation(); } // Clear all row selections source.ClearRowSelection(true /*resetAnchorRowIndex*/); } else { int rowIndex = source.DataConnection.IndexOf(e.NewValue); if (rowIndex == -1) { // Silently fail if the provided dataItem is not found. return; } if (rowIndex != source.CurrentRowIndex) { if (!source.EndEdit(true /*commitChanges*/, true /*exitEditingMode*/)) { // Edited value couldn't be committed or aborted d.SetValueNoCallback(e.Property, e.OldValue); throw DataGridError.DataGrid.CommitFailedCannotCompleteOperation(); } if (source.IsRowOutOfBounds(rowIndex)) { return; } } try { source._noSelectionChangeCount++; source.ClearRowSelection(rowIndex /*rowIndexException*/, true /*resetAnchorRowIndex*/); int columnIndex = source.CurrentColumnIndex; if (columnIndex == -1) { columnIndex = source.ColumnsInternal.FirstVisibleColumn == null ? -1 : source.ColumnsInternal.FirstVisibleColumn.Index; } if (columnIndex == -1 || source.IsRowOutOfBounds(rowIndex)) { return; } bool success = source.SetCurrentCellCore(columnIndex, rowIndex/*, false, false*/); Debug.Assert(success); } finally { source.NoSelectionChangeCount--; } } } }
private static void OnRowHeightPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { DataGrid source = d as DataGrid; Debug.Assert(source != null, "The source is not an instance of DataGrid!"); Debug.Assert(typeof(double).IsInstanceOfType(e.NewValue), "The value is not an instance of double!"); double value = (double)e.NewValue; if (!source.IsHandlerSuspended(e.Property)) { if (value < source.MinRowHeight) { value = source.MinRowHeight; } if (value > DataGridRow.DATAGRIDROW_maximumHeight) { d.SetValueNoCallback(e.Property, e.OldValue); throw DataGridError.DataGrid.ValueMustBeLessThanOrEqualTo("value", "RowHeight", DataGridRow.DATAGRIDROW_maximumHeight); } // Update the display rows source.SuspendLayout(); try { for (int childIndex = 0; childIndex < source.DisplayedAndEditedRowCount; childIndex++) { DataGridRow row = source._cells.Children[childIndex] as DataGridRow; row.Height = value; // } } finally { source.ResumeLayout(false); } source.PerformLayout(true /* forceDataCellsHorizontalLayout */); // Clear the prefetched and recycled rows; This needs to be done after updating the displayed rows // because the update might add recyclable rows that we want to discard source._prefetchedRows.Clear(); source._recyclableRows.Clear(); } }
/// <summary> /// IsReadOnlyProperty property changed handler. /// </summary> /// <param name="d">DataGrid that changed its IsReadOnly.</param> /// <param name="e">DependencyPropertyChangedEventArgs.</param> private static void OnIsReadOnlyPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { DataGrid dataGrid = (DataGrid)d; if (!dataGrid.IsHandlerSuspended(e.Property)) { bool value = (bool)e.NewValue; if (value && !dataGrid.CommitEdit(DataGridEditingUnit.Row, true /*exitEditing*/)) { d.SetValueNoCallback(e.Property, e.OldValue); throw DataGridError.DataGrid.CommitFailedCannotCompleteOperation(); } } }
/// <summary> /// SelectedItemProperty property changed handler. /// </summary> /// <param name="d">DataGrid that changed its SelectedItem.</param> /// <param name="e">DependencyPropertyChangedEventArgs.</param> private static void OnSelectedItemPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { DataGrid dataGrid = (DataGrid)d; if (!dataGrid.IsHandlerSuspended(e.Property)) { int rowIndex = (e.NewValue == null) ? -1 : dataGrid.DataConnection.IndexOf(e.NewValue); if (rowIndex == -1) { // If the Item is null or it's not found, clear the Selection if (!dataGrid.CommitEdit(DataGridEditingUnit.Row, true /*exitEditing*/)) { // Edited value couldn't be committed or aborted d.SetValueNoCallback(e.Property, e.OldValue); throw DataGridError.DataGrid.CommitFailedCannotCompleteOperation(); } // Clear all row selections dataGrid.ClearRowSelection(true /*resetAnchorRowIndex*/); } else { dataGrid.SetValueNoCallback(DataGrid.SelectedIndexProperty, rowIndex); if (rowIndex != dataGrid.CurrentRowIndex) { if (!dataGrid.CommitEdit(DataGridEditingUnit.Row, true /*exitEditing*/)) { // Edited value couldn't be committed or aborted d.SetValueNoCallback(e.Property, e.OldValue); throw DataGridError.DataGrid.CommitFailedCannotCompleteOperation(); } if (dataGrid.IsRowOutOfBounds(rowIndex)) { return; } } try { dataGrid._noSelectionChangeCount++; dataGrid.ClearRowSelection(rowIndex /*rowIndexException*/, true /*resetAnchorRowIndex*/); int columnIndex = dataGrid.CurrentColumnIndex; if (columnIndex == -1) { columnIndex = dataGrid.ColumnsInternal.FirstVisibleColumn == null ? -1 : dataGrid.ColumnsInternal.FirstVisibleColumn.Index; } if (columnIndex == -1 || dataGrid.IsRowOutOfBounds(rowIndex)) { return; } bool success = dataGrid.SetCurrentCellCore(columnIndex, rowIndex/*, false, false*/); Debug.Assert(success); } finally { dataGrid.NoSelectionChangeCount--; } } } }