Search code examples
c#.netwpfwpfdatagrid

Can I intercept a paste into a DataGrid cell?


I have a DataGrid with columns of different types that I add in code. I have subclassed the standard data grid in order that I can override the OnExecutedPaste method etc. However, this only fires if the user pastes while no cell is in edit mode; if a cell is in edit mode, the clipboard content just gets pasted into the cell. I want to trap the paste event so that if the clipboard contains multiple values (e.g. data from Excel) then I can put each value in a different cell.

Can I intercept the paste event before the cell handles it? Hopefully without subclassing all the columns and implementing my own cell generation, etc.!


Solution

  • You probably don't need to subclass the Grid. That is more a WinForms thing. I don't know what columntypes you need but maybe this can point you in the right direction:

    DataObject.AddPastingHandler(yourControl, PastingHandler);

    You could create custom ColumnTypes derived from DataGridBoundColumn. That is pretty simple and then attach the pastinghandler to the editcontrol.

    namespace StackOverflow
    {
        public class CustomColumn : DataGridBoundColumn
        {
            protected override FrameworkElement GenerateElement(DataGridCell cell, object dataItem)
        {
            TextBlock block = new TextBlock();
            CustomColumn column = (CustomColumn)cell.Column;
            Binding binding = (Binding)column.Binding;
            if (binding != null)
            {
                // Binde den ausgewählten Wert
                Binding cellBinding = new Binding(binding.Path.Path);
                cellBinding.Source = dataItem;
                cellBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
                cellBinding.ValidatesOnDataErrors = true;
                cellBinding.ValidatesOnExceptions = true;
                cellBinding.NotifyOnValidationError = true;
                cellBinding.ValidatesOnNotifyDataErrors = true;
                cellBinding.Mode = BindingMode.OneWay;
    
                block.SetBinding(TextBlock.TextProperty, cellBinding);
    
            }
    
            return block;
        }
    
        protected override FrameworkElement GenerateEditingElement(DataGridCell cell, object dataItem)
        {
            TextBox box = new TextBox();
            CustomColumn column = (CustomColumn)cell.Column;
            Binding binding = (Binding)column.Binding;
            if (binding != null)
            {
                // Binde den ausgewählten Wert
                Binding cellBinding = new Binding(binding.Path.Path);
                cellBinding.Source = dataItem;
                cellBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
                cellBinding.ValidatesOnDataErrors = true;
                cellBinding.ValidatesOnExceptions = true;
                cellBinding.NotifyOnValidationError = true;
                cellBinding.ValidatesOnNotifyDataErrors = true;
                cellBinding.Mode = BindingMode.TwoWay;
    
                box.SetBinding(TextBlock.TextProperty, cellBinding);
    
            }
    
                DataObject.AddPastingHandler(box, PastingHandler);
                return box;
            }
    
            private void PastingHandler(object sender, DataObjectPastingEventArgs e)
            {
                TextBox textBox = sender as TextBox;
                if (textBox == null)
                {
                    return;
                }
    
                if (e.DataObject.GetDataPresent(typeof(string)))
                {
                    //Read input
                    string pasteText = e.DataObject.GetData(typeof(string)) as string;
                    // Kommt ein neuer String zurück, wird dieser eingefügt und die ursprüngliche Operation abgebrochen.
                    if (!string.IsNullOrEmpty(pasteText))
                    {
                        // Neuen Text einbringen
                        textBox.Text = pasteText;
                        // Restliches Einfügen abbrechen
                        e.CancelCommand();
                    }
                }
            }
        }
    }