C1Flexgrid for Silverlight provides clipboard support and handles copy/paste operations on its own. However, if a CellRange is selected that includes hidden row/column, then the data from that hidden row/column gets copied and, consequently, pasted to the grid itself or in the external editors.

This is the default behavior of C1Flexgrid. However, this might not match the user's requirement. In this blog we look forward to provide a solution which handles this behavior and provide Clipboard operations only for visible cells.

Lets begin adding an event handler to the PreviewKeyDown event of C1FlexGrid in the page xaml. In code, populate the grid with few rows and columns (including a hidden column).

public MainPage()
{
InitializeComponent();

//Add few rows and columns
for (int i = 0; i < 5; i++)
{
c1FlexGrid1.Rows.Add(new C1.Silverlight.FlexGrid.Row());
c1FlexGrid1.Columns.Add(new C1.Silverlight.FlexGrid.Column() { Header = i.ToString() });
}

//Hide 2nd column
c1FlexGrid1.Columns[2].Visible = false;

//Populate the grid
for (int r = 0; r < 5; r++)
{
for (int c = 0; c < 5; c++)
{
c1FlexGrid1[r, c] = string.Format("({0}, {1})", r, c);
}
}
}


Now comes the actual action; wherein we handle Copy/Paste.

Copy Operation


Lets begin with handling of Copy operation, i.e. CTRL+C; within PreviewKeyDown event. Please see the code below which includes comments to make it self-explanatory:


//Detect CTRL+C
if (e.Key == Key.C && (Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control)
{
//If CTRL+C is pressed, we'll hanlde it ourselves
e.Handled = true;
C1.Silverlight.FlexGrid.CellRange cr;
//Get selected cellrange
cr = this.c1FlexGrid1.Selection;

//Create a StringBuilder object
var sb = new System.Text.StringBuilder();

//Add celldata to stringbuilder
//with "\t" appended after every entry
//and skip column that are not visible
for (int i = cr.TopRow; i <= cr.BottomRow; i++)
{
for (int j = cr.LeftColumn; j <= cr.RightColumn; j++)
{
if (this.c1FlexGrid1.Columns[j].Visible)
{
sb.Append(this.c1FlexGrid1[i, j].ToString());
sb.Append("\t");
}
}

//Remove "\t" fom the last position of row
//and add a new line instead
sb.Remove(sb.Length - 1, 1);
sb.Append(Environment.NewLine);
}

//Place the entire string to Clipboard
Clipboard.SetText(sb.ToString());
}

Paste Operation


Paste operation, i.e. CTLR+V, is handled in the following code :


if (e.Key == Key.V && (Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control)
{
//If CTRL+V is pressed, handle the code execution
e.Handled = true;

//Get data from Clipboard
string StrPaste = Clipboard.GetText();

if (StrPaste != null)
{
//Populate array "string[] rows" with data
rows = StrPaste.Split(new string[] { Environment.NewLine },StringSplitOptions.RemoveEmptyEntries);
}

C1.Silverlight.FlexGrid.CellRange cr;
//Get selected cellrange
cr = this.c1FlexGrid1.Selection;
int count = 0;

for (int i = cr.TopRow; i <= cr.BottomRow; i++)
{
//Create an array to store data of each row
string[] arr;
arr = rows[count].Split(new string[] { "\t" }, StringSplitOptions.None);
int z = 0;

for (int j = cr.LeftColumn; j <= cr.RightColumn; j++)
{
if (this.c1FlexGrid1.Columns[j].Visible)
{
//Parse array "arr" and store data in grid's cell
//while skipping invisible columns
this.c1FlexGrid1[i, j] = arr[z];
//verify if it is only one row (in arr[])
if (arr.Count() > 1)
{
z++;
}
}
}
if (rows.Count() - 1 > count)
count++;
}
}


Here, "rows" refers to array of strings that I declared outside the event block.

Before I finish off, I need to add that the above implementation takes care of data copy/paste to/ from MS Excel too. Say, you copied some data from C1Flexgrid, then you can paste it to MS Excel, because data is put into clipboard. Similarly, for the same reasons, you may copy data from Excel and paste it to C1FlexGrid, excluding the hidden columns.

Similar logic will work for hidden rows as well.

Download C# Sample

Download VB Sample