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.!
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();
}
}
}
}
}