I recently started using the WPF Datagrid with DataGridTemplateColumns containing the WPF AutoCompleteBox, but I'm finding trouble in implementing Clipboard.Paste functionality for these DataGridTemplateColumns.
I've managed to get Clipboard.Paste working with built-in DataGridColumns via Vishal's guide here, but it doesn't work with DataGridTemplateColumns.
Delving into the OnPastingCellClipboardContent method in the DataGridColumn class, it appears that fe.GetBindingExpression(CellValueProperty) is returning null rather than the required BindingExpression.
Can anyone point me to the right direction?
public virtual void OnPastingCellClipboardContent(object item, object cellContent)
{
BindingBase binding = ClipboardContentBinding;
if (binding != null)
{
// Raise the event to give a chance for external listeners to modify the cell content
// before it gets stored into the cell
if (PastingCellClipboardContent != null)
{
DataGridCellClipboardEventArgs args = new DataGridCellClipboardEventArgs(item, this, cellContent);
PastingCellClipboardContent(this, args);
cellContent = args.Content;
}
// Event handlers can cancel Paste of a cell by setting its content to null
if (cellContent != null)
{
FrameworkElement fe = new FrameworkElement();
fe.DataContext = item;
fe.SetBinding(Ce开发者_开发百科llValueProperty, binding);
fe.SetValue(CellValueProperty, cellContent);
BindingExpression be = fe.GetBindingExpression(CellValueProperty);
be.UpdateSource();
}
}
Thanks!
Using ClipboardContentBinding and setting the binding's Mode to TwoWay, seems to works.
GetBindingExpression then returns something not null (the binding on ClipboardContentBinding) and the UpdateSource does not fail.
I imagine this solution is limited to the case where you have a PropertyChanged event triggered on the source, which in turn update the control in the column's DataTemplate.
This is because for DataGridTemplateColumns there isnt a binding. The binding is taken care of in your datatemplate. The cell datatemplate just gets the item (the item in the row) and binds to it. there is no way for the column to know what is in the cell.
I have worked around this by creating my own columns. I derive from DataGridTextColumn (if i am doing one that has text input) and override the GenerateElement and GenerateEditingElement.
This way i still have the binding property that can be used for pasting.
Use ClipboardContentBinding
as shown:
<DataGridTemplateColumn
Header="First Name"
SortMemberPath="FirstName"
ClipboardContentBinding="{Binding FirstName}"
>
<DatGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding FirstName}" />
</DataTemplate>
</DatGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
...
</DataGridTemplateColumn>
</DataGridTemplateColumn>
Taken from here.
精彩评论