using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.Globalization; using System.IO; using System.Drawing; namespace Ucel.Base { internal class DataGridViewClipboardProvider : IClipboardProvider { #region IClipboardProvider Members private DataGridView ctl; public System.Windows.Forms.Control Control { get { return ctl; } set { ctl = value as DataGridView; } } public bool CanCopy { get { return ctl.SelectedCells.Count != 0; } } public bool CanCut { get { return CanCopy && CanClear; } } public bool CanPaste { get { string[,] data = GetClipboardData(); if (data == null) return false; // no valid data int height = data.GetLength(0); int width = data.GetLength(1); // Case 1: one cell selected. No support for inserting new rows if (ctl.SelectedCells.Count == 1) { DataGridViewCell cell = ctl.SelectedCells[0]; int maxWidth = ctl.ColumnCount - cell.ColumnIndex + 1; int maxHeight = ctl.RowCount - cell.RowIndex + 1; return height <= maxHeight && width <= maxWidth; } // Case 2: more cells selected. Selection must be the same size as the data else { if (ctl.SelectedCells.Count != height * width) return false; DataGridViewCell cell1 = ctl.SelectedCells[0]; DataGridViewCell cell2 = ctl.SelectedCells[ctl.SelectedCells.Count-1]; if (Math.Abs(cell2.ColumnIndex-cell1.ColumnIndex)+1 != width) return false; if (Math.Abs(cell2.RowIndex-cell1.RowIndex)+1 != height) return false; } return true; } } public bool CanClear { get { if (ctl.SelectedCells.Count == 0) return false; // Nothing to clear bool bEnabled = true; foreach (DataGridViewCell c in ctl.SelectedCells) bEnabled &= !c.ReadOnly; return bEnabled; } } public bool CanSelectAll { get { return true; } } public void Copy() { Clipboard.SetDataObject(ctl.GetClipboardContent()); } public void Cut() { Copy(); Clear(); } public void Paste() { string[,] data = GetClipboardData(); int height = data.GetLength(0); int width = data.GetLength(1); int baseRow = ctl.SelectedCells[0].RowIndex; int baseCol = ctl.SelectedCells[0].ColumnIndex; for (int i = 1; i < ctl.SelectedCells.Count; i++) { baseRow = Math.Min(baseRow, ctl.SelectedCells[i].RowIndex); baseCol = Math.Min(baseCol, ctl.SelectedCells[i].ColumnIndex); } for (int row = 0; row < height; row++) for (int col = 0; col < width; col++) ctl.Rows[row+baseRow].Cells[col+baseCol].Value = data[row, col]; } public void Clear() { foreach (DataGridViewCell c in ctl.SelectedCells) c.Value = null; } public void SelectAll() { ctl.SelectAll(); } #endregion private string[,] GetClipboardData() { IDataObject obj = Clipboard.GetDataObject(); if (obj == null) return null; string data = obj.GetData(DataFormats.CommaSeparatedValue) as string; if (data == null) { MemoryStream ms = obj.GetData(DataFormats.CommaSeparatedValue) as MemoryStream; if (ms == null) return null; using (StreamReader sr = new StreamReader(ms)) { data = sr.ReadToEnd(); if (data.EndsWith("\0")) data = data.Substring(0, data.LastIndexOf('\0')); } } string[] lines = data.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); if (lines.Length == 0) return null; string [] elements = lines[0].Split(new char[] {'\t', CultureInfo.CurrentCulture.TextInfo.ListSeparator[0]}, StringSplitOptions.RemoveEmptyEntries); if (elements.Length == 0) return null; string [,] retData = new string[lines.Length, elements.Length]; for (int i=0; i