/// <summary> /// Replaces the selected cells with the data. Cell selection and the data table must have matching dimensions, either 1:n, n:1 or n:x*n. /// </summary> /// <param name="dataGrid">The data grid.</param> /// <param name="data">The data.</param> /// <remarks>The cell selection is assumed to be a rectangular area.</remarks> /// <returns><c>true</c> if the dimensions of data and cell selection did match and the cells data has been replaced; otherwise <c>false</c>.</returns> public static bool PasteCells([NotNull] this DataGrid dataGrid, [NotNull, ItemNotNull] IList <IList <string> > data) { var numberOfDataRows = data.Count; if (data.Count < 1) { return(false); } var firstRow = data[0]; var numberOfDataColumns = firstRow.Count; var selectedCells = dataGrid.GetVisibleSelectedCells(); if ((selectedCells == null) || !selectedCells.Any()) { return(false); } var selectedColumns = selectedCells .Select(cellInfo => cellInfo.Column) .Distinct() // ReSharper disable once PossibleNullReferenceException .Where(column => column.Visibility == Visibility.Visible) .OrderBy(column => column.DisplayIndex) .ToArray(); var selectedRows = selectedCells .Select(cellInfo => cellInfo.Item) .Distinct() // ReSharper disable once AssignNullToNotNullAttribute .OrderBy(item => dataGrid.Items.IndexOf(item)) .ToArray(); if ((selectedColumns.Length == 1) && (selectedRows.Length == 1)) { // n:1 => n:n, extend selection to match data var selectedColumn = selectedColumns[0]; selectedColumns = dataGrid.Columns // ReSharper disable PossibleNullReferenceException .Where(col => col.DisplayIndex >= selectedColumn.DisplayIndex) // ReSharper restore PossibleNullReferenceException .OrderBy(col => col.DisplayIndex) .Where(col => col.Visibility == Visibility.Visible) .Take(numberOfDataColumns) .ToArray(); var selectedItem = selectedRows[0]; selectedRows = dataGrid.Items .Cast <object>() // ReSharper disable once AssignNullToNotNullAttribute .Skip(dataGrid.Items.IndexOf(selectedItem)) .Take(numberOfDataRows) .ToArray(); } var verticalFactor = selectedRows.Length / numberOfDataRows; if ((numberOfDataRows * verticalFactor) != selectedRows.Length) { return(false); } var horizontalFactor = selectedColumns.Length / numberOfDataColumns; if ((numberOfDataColumns * horizontalFactor) != selectedColumns.Length) { return(false); } // n:x*n foreach (var row in Enumerate.AsTuples(selectedRows, Repeat(data, verticalFactor))) { // ReSharper disable AssignNullToNotNullAttribute, PossibleNullReferenceException foreach (var column in Enumerate.AsTuples(selectedColumns, Repeat(row.Item2, horizontalFactor))) { column.Item1.OnPastingCellClipboardContent(row.Item1, column.Item2); } // ReSharper restore AssignNullToNotNullAttribute, PossibleNullReferenceException } return(true); }
/// <summary> /// Replaces the selected cells with the data. Cell selection and the data table must have matching dimensions, either 1:n, n:1 or n:x*n. /// </summary> /// <param name="dataGrid">The data grid.</param> /// <param name="data">The data.</param> /// <remarks>The cell selection is assumed to be a rectangular area.</remarks> /// <returns><c>true</c> if the dimensions of data and cell selection did match and the cells data has been replaced; otherwise <c>false</c>.</returns> public static bool PasteCells(this DataGrid dataGrid, IList <IList <string> > data) { Contract.Requires(dataGrid != null); Contract.Requires(data != null); // Contract.Requires(Contract.ForAll(data, item => item != null)); var numberOfDataRows = data.Count; if (data.Count < 1) { return(false); } var firstRow = data[0]; Contract.Assume(firstRow != null); // Contract.Assume(Contract.ForAll(firstRow, item => item != null)); var numberOfDataColumns = firstRow.Count; var selectedCells = dataGrid.GetVisibleSelectedCells(); if ((selectedCells == null) || !selectedCells.Any()) { return(false); } var selectedColumns = selectedCells .Select(cellInfo => cellInfo.Column) .Distinct() .Where(column => column.Visibility == Visibility.Visible) .OrderBy(column => column.DisplayIndex) .ToArray(); var selectedRows = selectedCells .Select(cellInfo => cellInfo.Item) .Distinct() .OrderBy(item => dataGrid.Items.IndexOf(item)) .ToArray(); if ((selectedColumns.Length == 1) && (selectedRows.Length == 1)) { // n:1 => n:n, extend selection to match data var selectedColumn = selectedColumns[0]; selectedColumns = dataGrid.Columns .Where(col => col.DisplayIndex >= selectedColumn.DisplayIndex) .OrderBy(col => col.DisplayIndex) .Where(col => col.Visibility == Visibility.Visible) .Take(numberOfDataColumns) .ToArray(); var selectedItem = selectedRows[0]; selectedRows = dataGrid.Items .Cast <object>() .Skip(dataGrid.Items.IndexOf(selectedItem)) .Take(numberOfDataRows) .ToArray(); } var verticalFactor = selectedRows.Length / numberOfDataRows; if ((numberOfDataRows * verticalFactor) != selectedRows.Length) { return(false); } var horizontalFactor = selectedColumns.Length / numberOfDataColumns; if ((numberOfDataColumns * horizontalFactor) != selectedColumns.Length) { return(false); } // n:x*n Enumerate.AsTuples(selectedRows, Repeat(data, verticalFactor)) .ForEach(row => Enumerate.AsTuples(selectedColumns, Repeat(row.Item2, horizontalFactor)) .ForEach(column => column.Item1.OnPastingCellClipboardContent(row.Item1, column.Item2))); return(true); }