Click here to Skip to main content
15,072,311 members
Articles / Desktop Programming / WPF
Posted 26 Aug 2011


20 bookmarked

Implementing Copy and Paste for a WPF DataGrid in .NET 4

Rate me:
Please Sign up or sign in to vote.
5.00/5 (3 votes)
31 Aug 2011CPOL4 min read
Using the DataZGrid provided by .NET 4, this article shows how to copy and paste between cells.


Update - See restriction 3 below.

Using the standard DataGrid that was added with .NET 4, I found that I needed to implement copy and paste. Searching the internet came up with solutions that either worked with Silverlight or with some sort of pre-release version that you could add to Visual Studio 2008 (.NET 3).

To my horror, I had to actually figure something out and write some code. I'm very new to WPF and have spent the last few months copying example code off the internet and modifying it for my use but I think I have finally written something that might be of use to other people, so here it is.

Credit goes to the following two pages that helped, and some code was taken from the second one (credited in comments):

The solution allows you to do some limited copy and pasting between cells. In the example, I have a table of people with fields first name, second name, and legs (a number - usually 2). In the application I was working on, it made no sense to copy from one column to another. So in this example, you can't copy the legs column to the first name column (for example). This is intentional and the restriction could be removed easily by deleting some checks.

Restrictions / problems to solve!

  1. It only deals with strings or integers. It should be easy to expand on the types allowed with more code but perhaps that can be avoided completely with a different implementation.
  2. The clipboard is only converted from one particular format. I need to see if copying from Excel works - otherwise I probably need to put some code back into DatagridHelper that I removed!
  3. Important If the rows are re-ordered, it breaks this code! For this reason, I suggest you don't use this code.

Reto Ravisio saw this article and provided a much better solution. I have taken that, changed it slightly, and provided a complete solution file that uses his code:

Hopefully this will help beginners like myself use that code.

Using the code

I will go over some of the code you have to copy into your project, but you'll have to see the entire solution to get all the required code. This is a tester to show you the main principles so you can decide if it's for you.

The DataGrid is declared like this:

<DataGrid Name="dataGrid1" ItemsSource="{Binding PeopleList}" 

Note that the SelectionUnit is set to Cell. This allows individual cells to be selected rather than the whole row. The items are taken from an ObserverableCollection and the columns are automatically generated.

The KeyDown event is set to detect the paste operation:

void dataGrid1_KeyDown(object sender, KeyEventArgs e)
  if (e.Key == Key.V &&
      (Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control)
    if (ValidatePaste() == false)

         Clipboard.GetData(DataFormats.Text) as string);

As you can see, a View Model is used.

The View Model Paste function uses the ClipboardHelper class (taken from the MSDN blog mentioned in the introduction) to convert the string version of the copied cells into a list of string arrays representing the cells on each row. Then it loops through the target rows setting the ObservableCollection.

Reflection is used to set the properties in the collection having only a string representing the property name. This avoids having a switch statement checking the display index value and matching that up to a property. It would have made the code very tedious to write and not easily re-usable.

The SetProperty function implements that functionality:

private void SetProperty(Person person, string propertyName, string cellItem)
  // Use reflection to set the property to the value
  Type type = person.GetType();
  PropertyInfo prop = type.GetProperty(propertyName);
  if (prop == null)
    Debug.WriteLine("Property not found: " + propertyName);
  if (prop.PropertyType == typeof(string)) // only caters for string or integer types
    prop.SetValue(person, cellItem, null);
    prop.SetValue(person, int.Parse(cellItem), null);

You can see in the code above where the restriction on having only strings or integers comes from.

The People class is a simple container class that implements INotifyPropertyChanged:

class Person : INotifyPropertyChanged
    public Person(string first, string second)
      FirstName = first;
      SecondName = second;
      Legs = 2;
    public string FirstName { set; get; }
    public string SecondName { set; get; }
    public int Legs { set; get; }

#region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    public virtual void OnPropertyChanged(string propertyName)
        if (this.PropertyChanged != null)
            this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));


The code which populates the map of property names and display indexes (used in the VM Paste function) relies on this bit of code in the code-behind:

private void dataGrid1_ColumnReordered(object sender, DataGridColumnEventArgs e)
    foreach (DataGridColumn col in dataGrid1.Columns)
        viewModel.AddColumnMapping(col.DisplayIndex, col.SortMemberPath);

I'm assuming that the SortMemberPath will always be the same as the property name in the People class. It was in my case.


  • 2011-09-01: A new version which gets the column information when the columns are re-ordered rather than when loaded. Updated a downloadable complete solution based on Reto's article.


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

United Kingdom United Kingdom
No Biography provided

Comments and Discussions

QuestionBest Way? Pin
Reto Ravasio28-Aug-11 1:04
MemberReto Ravasio28-Aug-11 1:04 
AnswerRe: Best Way? Pin
Peter_Smithson28-Aug-11 21:30
MemberPeter_Smithson28-Aug-11 21:30 
GeneralRe: Best Way? Pin
Reto Ravasio29-Aug-11 7:44
MemberReto Ravasio29-Aug-11 7:44 
GeneralRe: Best Way? Pin
Peter_Smithson30-Aug-11 21:24
MemberPeter_Smithson30-Aug-11 21:24 
GeneralRe: Best Way? Pin
Peter_Smithson30-Aug-11 23:11
MemberPeter_Smithson30-Aug-11 23:11 
GeneralRe: Best Way? Pin
Reto Ravasio31-Aug-11 12:44
MemberReto Ravasio31-Aug-11 12:44 
GeneralRe: Best Way? Pin
Peter_Smithson31-Aug-11 22:13
MemberPeter_Smithson31-Aug-11 22:13 
GeneralRe: Best Way? Pin
Reto Ravasio1-Sep-11 10:14
MemberReto Ravasio1-Sep-11 10:14 
I downloaded the code and have given it a try. I think I understand the changes you did but I think your new code works propperly only when you have data from one single colum in the buffer. As soon as you want to copy more then one colum, the data is pasted allover the grid.

Does the download include the latest version? because you talk about an additional loop that I can't find?

I didn't really plan to include something downloadable in my article because the code as it is is short enough for just beeing pasted into an already running application.

You're also right that your article currently doesnt add any value but I was hoping you'd come up with something even excel can't do.

GeneralRe: Best Way? Pin
Peter_Smithson5-Sep-11 5:54
MemberPeter_Smithson5-Sep-11 5:54 
AnswerRe: Best Way? Pin
Member 85358323-Jan-12 2:43
MemberMember 85358323-Jan-12 2:43 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.