Clipboard Operations in WinUI TreeGrid

14 Apr 202123 minutes to read

SfTreeGrid provides support to the clipboard operations such as cut, copy, and paste the data within control and between other applications such as Notepad and Excel. The clipboard operations of copy and paste are enabled by default. You can copy the selected nodes/cells from tree grid by clicking Ctrl+C and can paste the content from Clipboard to tree grid by clicking Ctrl+V.

Copy

The copy operation works based on the CopyOption property.

GridCopyOption provides the following options:

You can use the IncludeHeaders, IncludeFormat, and IncludeHiddenColumn options along with the CopyData option.

<treeGrid:SfTreeGrid
                Name="treeGrid"
                CopyOption="CopyData,IncludeHeaders"
                AllowFiltering="True"
                AutoExpandMode="RootNodesExpanded"
                AutoGenerateColumns="False"
                ChildPropertyName="Children"
                ColumnWidthMode="Star"                       
                ExpanderColumn="FirstName"
                ItemsSource="{Binding Persons}" />
this.treeGrid.CopyOption = GridCopyOptions.CopyData | GridCopyOptions.IncludeHeaders;

WinUI treegrid shows with Copied content pasted in notepad

Paste

The paste operation works based on the PasteOption property.

GridPasteOption provides the following options:

  • None: Disables paste in tree grid.

  • PasteData: Enables paste in tree grid. When an incompatible value is pasted into a record/cell, the pasting operation is skipped for that particular record/cell.

  • ExcludeFirstLine: Pastes data copied with IncludeHeaders copy option.

  • IncludeHiddenColumn: Pastes the values in hidden columns also.

You can use the ExcludeFirstLine and IncludeHiddenColumn options along with the PasteData option.

<treeGrid:SfTreeGrid
                Name="treeGrid"
                CopyOption="CopyData,IncludeHeaders"
                PasteOption="PasteData,ExcludeFirstLine"
                AllowFiltering="True"
                AutoExpandMode="RootNodesExpanded"
                AutoGenerateColumns="False"
                ChildPropertyName="Children"
                ColumnWidthMode="Star"                       
                ExpanderColumn="FirstName"
                ItemsSource="{Binding Persons}" />
this.treeGrid.CopyOption = GridCopyOptions.CopyData | GridCopyOptions.IncludeHeaders;

this.treeGrid.PasteOption = GridPasteOptions.PasteData | GridPasteOptions.ExcludeFirstLine;

WinUI treegrid shows with Copied record pasted in new record

Cut

The cut operation works based on the CopyOption property.

GridCopyOption provides the following options:

You can use the IncludeHeaders, IncludeFormat, and IncludeHiddenColumn options along with CutData option.

<treeGrid:SfTreeGrid
                Name="treeGrid"
                CopyOption="CutData,IncludeHeaders" 
                AllowFiltering="True"
                AutoExpandMode="RootNodesExpanded"
                AutoGenerateColumns="False"
                ChildPropertyName="Children"
                ColumnWidthMode="Star"                       
                ExpanderColumn="FirstName"
                ItemsSource="{Binding Persons}" />
this.treeGrid.CopyOption = GridCopyOptions.CutData | GridCopyOptions.IncludeHeaders;

WinUI treegrid shows with Data from the record is cut and pasted in notepad

Events

CopyContent

The CopyContent event occurs when copy/cut the cells in tree grid. GridCopyPasteEventArgs provides information for to the CopyContent event. You can cancel copy operation by handling this event.

this.treeGrid.CopyContent += TreeGrid_CopyContent;

private void TreeGrid_CopyContent(object sender, GridCopyPasteEventArgs e)
{
    if (((e.OriginalSender as SfTreeGrid).SelectedItem as Person).Id == 11110)
        e.Handled = true;
}

PasteContent

The PasteContent event occurs when paste the clipboard value into tree grid. GridCopyPasteEventArgs provides information to the PasteContent event. You can cancel the paste operation by handling this event.

this.treeGrid.PasteContent += TreeGrid_PasteContent;

private void TreeGrid_PasteContent(object sender, GridCopyPasteEventArgs e)
{
    if (((e.OriginalSender as SfTreeGrid).SelectedItem as Person).Id == 11110)
        e.Handled = true;
}

CopyCellContent

The CopyCellContent event occurs when a cell is being copied/cut. TreeGridCopyPasteCellEventArgs provides information to the CopyGridCellContent event, which has the following members:

You can change the text copied to clipboard by changing the ClipBoardValue.

this.treeGrid.CopyCellContent += TreeGrid_CopyCellContent;

private void TreeGrid_CopyCellContent(object sender, TreeGridCopyPasteCellEventArgs e)
{
            
}

The following code example changes the clipboard value to 100 instead of cell value 1005 in tree grid.

private void TreeGrid_CopyCellContent(object sender, TreeGridCopyPasteCellEventArgs e)
{
    if (e.Column.MappingName == "OrderID" && (e.RowData as OrderDetails).OrderID == 1005)
        e.ClipBoardValue = 100;
}

WinUI treegrid shows with Copied data customized through CopyCellContent event

The following code example demonstrates how to handle the copy operation when MappingName of a Column is Id.

private void TreeGrid_CopyCellContent(object sender, TreeGridCopyPasteCellEventArgs e)
{
    if (e.Column.MappingName == "Id")
        e.Handled = true;
}

WinUI treegrid shows with Copy operation for a column handled through CopyCellContent event

PasteCellContent

The PasteGridCellContent event occurs when a cell is being pasted. TreeGridCopyPasteCellEventArgs provides information to the PasteGridCellContent event, which has the following members:

You can paste the text to tree grid by changing the ClipBoardValue.

this.treeGrid.PasteCellContent += TreeGrid_PasteCellContent;

private void TreeGrid_PasteCellContent(object sender, TreeGridCopyPasteCellEventArgs e)
{
            
}

The following code example changes the clipboard value to David instead of clipboard value Warner.

private void TreeGrid_PasteCellContent(object sender, TreeGridCopyPasteCellEventArgs e)
{
    if (e.Column.MappingName == "FirstName" && (e.RowData as Person).FirstName == "Warner")
        e.ClipBoardValue = "David";
}

WinUI treegrid shows with Data of a column customized when pasting through PasteCellContent event

The following code example demonstrates how to handle the paste operation when MappingName of column is Id.

private void TreeGrid_PasteCellContent(object sender, TreeGridCopyPasteCellEventArgs e)
{
    if (e.Column.MappingName == "Id")
        e.Handled = true;
}

WinUI treegrid shows with Paste operation of a column is handled through PasteCellContent event

Handle the clipboard operations programmatically

Copy the node programmatically

Copy the selected nodes in tree grid using the Copy method in TreeGridClipboardController of tree grid.

this.treeGrid.TreeGridCopyPaste.Copy();

Copy a record by selecting the record using the MoveCurrentCell method and Copy method in TreeGridClipboardController of tree grid.

RowColumnIndex rowColumnIndex = new RowColumnIndex();
rowColumnIndex.RowIndex = 2;
rowColumnIndex.ColumnIndex = 2;
this.treeGrid.SelectionController.MoveCurrentCell(rowColumnIndex);
this.treeGrid.ClipboardController.Copy();

Copy multiple records by selecting a group of records using the SelectRows method and Copy method in TreeGridClipboardController of tree grid.

this.treeGrid.SelectionController.SelectRows(2, 5);
this.treeGrid.ClipboardController.Copy();

Paste to tree grid programmatically

Paste the clipboard value into tree grid using the Paste method in TreeGridClipboardController of tree grid.

this.treeGrid.ClipboardController.Paste();

Paste the clipboard value into selected record by selecting the record using the MoveCurrentCell method and Paste method in TreeGridClipboardController of tree grid.

RowColumnIndex rowColumnIndex = new RowColumnIndex();
rowColumnIndex.RowIndex = 1;
rowColumnIndex.ColumnIndex = 1;
this.treeGrid.SelectionController.MoveCurrentCell(rowColumnIndex);
this.treeGrid.ClipboardController.Paste();

Cut from tree grid programmatically

Cut the selected records/cells in tree grid using the Cut method in TreeGridClipboardController of tree grid.

this.treeGrid.ClipboardController.Cut();

Cut the entire record in tree grid by selecting whole tree grid using the SelectAll method and Cut method in TreeGridClipboardController of tree grid.

this.treeGrid.SelectionController.SelectAll();
this.treeGrid.ClipboardController.Cut();

Customize copy paste behavior

The tree grid processes the clipboard operations in the TreeGridClipboardController class. You can customize the default copy paste behaviors by overriding the TreeGridCutCopyPaste class and set it to SfTreeGrid.ClipboardController.

public class CustomClipboardController : TreeGridClipboardController
{
    public CustomClipboardController(SfTreeGrid sfTreeGrid) : base(sfTreeGrid)
    {
    }
}
public MainPage()
{
    this.InitializeComponent();
    this.treeGrid.ClipboardController = new CustomClipboardController(this.treeGrid);
}

Paste a record into selected rows

By default, you can copy a row and paste it into another row in tree grid. The following code example shows how to copy a row and paste it into all the selected rows by overriding the PasteRow method in the TreeGridClipboardController class.

public class CustomClipboardController : TreeGridClipboardController
{
    SfTreeGrid treeGrid { get; set; }
    public CustomClipboardController(SfTreeGrid sfTreeGrid) : base(sfTreeGrid)
    {
        this.treeGrid = sfTreeGrid;
    }

    protected override void PasteRow(object clipboardContent, object selectedRecords)
    {
        var text = clipboardContent.ToString();
        string[] clipBoardText = Regex.Split(text, @"\r\n");

        //Get the clipBoardText and check if the clipBoardText is more than one row
        //means call the base.
        if (clipBoardText.Count() > 1)
        {
            base.PasteRow(clipboardContent, selectedRecords);
            return;
        }
        var selectedRecord = this.treeGrid.SelectedItems;
        for (int i = 0; i < selectedRecord.Count; i++)
        {
            //Get the selected records for paste the copied row.
            selectedRecords = selectedRecord[i];

            //Call the PasteRow method with clipboardContent and selectedRecords
            base.PasteRow(clipboardContent, selectedRecords);
        }
    }
}

Select pasted records

By default, after pasting the clipboard value to tree grid, the selection is maintained in previously selected records. The following code example shows how to select the pasted records by overriding the PasteRow method in the TreeGridClipboardController class.

public class CustomClipboardController : TreeGridClipboardController
{
    SfTreeGrid treeGrid { get; set; }
    public CustomClipboardController(SfTreeGrid sfTreeGrid) : base(sfTreeGrid)
    {
        this.treeGrid = sfTreeGrid;
    }

    protected override void PasteRow(object clipboardcontent, object selectedRecords)
    {
        base.PasteRow(clipboardcontent, selectedRecords);

        // Add the selected record to list.
        this.treeGrid.SelectedItems.Add(selectedRecords);
    }
}

Create new records when pasting

By default, when paste the clipboard value to tree grid, it changes the values of the already existing records. The following code example shows how to add the copied records as new rows in tree grid by overriding the PasteRow method in the TreeGridClipboardController class.

public class CustomClipboardController : TreeGridClipboardController
{
    SfTreeGrid treeGrid { get; set; }
    public CustomClipboardController(SfTreeGrid sfTreeGrid) : base(sfTreeGrid)
    {
        this.treeGrid = sfTreeGrid;
    }

    protected override void PasteRows(object clipBoardRows)
    {
        var copiedRecord = (string[])clipBoardRows;
        int copiedRecordsCount = copiedRecord.Count();

        //Based on the clipboard count added the new record for paste
        if (copiedRecordsCount > 0)
        {
            //Get the viewModel for adding the record
            var record = this.treeGrid.DataContext as ViewModel;

            for (int i = 0; i < copiedRecordsCount; i++)
            {
                //Create the new instance for Model, for adding the new record
                EmployeeInfo entity = new EmployeeInfo();

                for (int j = 0; j < this.treeGrid.Columns.Count; j++)
                {
                    string[] values = Regex.Split(copiedRecord[i], @"\t");

                    //Adding the new record by using PasteToCell method by passing the 

                    //created data, particular column, and clipboard value
                    this.PasteCell(entity, this.treeGrid.Columns[j], values[j]);
                }

                //Added the pasted record in collection
                record.Employees.Add(entity);
            }
        }
    }
}

Paste data by custom column order

The data can be pasted only from the first column, by default. However, you can paste the copied data anywhere in the grid by deriving a new class from TreeGridClipboardController and overriding the PasteRow virtual method.

public class CustomClipboardController : TreeGridClipboardController
{
    SfTreeGrid treeGrid { get; set; }
    public CustomClipboardController(SfTreeGrid sfTreeGrid) : base(sfTreeGrid)
    {
        this.treeGrid = sfTreeGrid;
    }

    protected override void PasteRow(object clipboardContent, object selectedRecords)
    {
        // Splits the row into number of cells using \t.
        clipboardContent = Regex.Split(clipboardContent.ToString(), @"\t");
        var copyValue = (string[])clipboardContent;

        int columnIndex = 0;
        //Gets the currentCell column index.
        var index = this.treeGrid.SelectionController.CurrentCellManager.CurrentCell.ColumnIndex;
        foreach (var column in treeGrid.Columns)
        {
            if (index >= treeGrid.Columns.Count)
                return;
            if (copyValue.Count() <= this.treeGrid.Columns.IndexOf(column))
                break;
            // Calls the PasteToCell method and passes the copied data and pastes the column index.
            PasteCell(selectedRecords, this.treeGrid.Columns[index], copyValue[columnIndex]);
            index++;
            columnIndex++;
        }
    }
}