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