I am using the Xceed grid in my application to allow the user to enter monetary values into cells. They would like to be able to copy and paste values between cells in the grid, but this is not supported by the grid natively. Support from the Clipboard is very good in WPF (via the System.Windows.Clipboard static class) so this actually is not a particularly difficult thing to implement. My aim is to write a generic reusable solution here that will work for any Xceed grid in my application, rather than a specific one, so I neither want to do any copying or updating of actual data. What we first need to do is register execution handlers for the ApplicationCommands.Copy and the ApplicationCommands.Paste commands against the DataGrid. We then either copy the content of the current cell or paste into it depending on which command is executed. I think the best place to perform generic event handling against a class is in the static initialiser of the App class, like follows:
static App()
{
CommandManager.RegisterClassCommandBinding(typeof(DataGridControl), newCommandBinding(ApplicationCommands.Paste, HandleXceedPasteCommandExecuted));
CommandManager.RegisterClassCommandBinding(typeof(DataGridControl), newCommandBinding(ApplicationCommands.Copy, HandleXceedCopyCommandExecuted));
}
private static void HandleXceedCopyCommandExecuted(object sender, ExecutedRoutedEventArgs e)
{
DataGridControl dataGridControl = sender as DataGridControl;
if (dataGridControl != null)
{
Xceed.Wpf.DataGrid.Row row = (Xceed.Wpf.DataGrid.Row) dataGridControl.ItemContainerGenerator.ContainerFromItem(dataGridControl.CurrentItem);
Xceed.Wpf.DataGrid.Cell currentCell = row.Cells[dataGridControl.CurrentColumn.Index];
if (currentCell != null && currentCell.HasContent)
{
Clipboard.SetText(currentCell.Content.ToString());
}
}
}
public delegate void Callback();
private static void HandleXceedPasteCommandExecuted(object sender, ExecutedRoutedEventArgs e)
{
DataGridControl dataGridControl = sender as DataGridControl;
if (dataGridControl != null && Clipboard.ContainsText())
{
Xceed.Wpf.DataGrid.Row row = (Xceed.Wpf.DataGrid.Row)dataGridControl.ItemContainerGenerator.ContainerFromItem(dataGridControl.CurrentItem);
Xceed.Wpf.DataGrid.Cell currentCell = row.Cells[dataGridControl.CurrentColumn.Index];
if (!currentCell.ReadOnly)
{
string text = Clipboard.GetText();
currentCell.BeginEdit();
Application.Current.Dispatcher.Invoke(DispatcherPriority.Input, (Callback)delegate
{
if (Keyboard.FocusedElement != null)
{
foreach (char c in text)
{
TextComposition textComposition = new TextComposition(InputManager.Current, Keyboard.FocusedElement, new string(c, 1));
TextCompositionEventArgs textCompositionEventArgs = new TextCompositionEventArgs(Keyboard.PrimaryDevice, textComposition);
textCompositionEventArgs.RoutedEvent = UIElement.TextInputEvent;
Keyboard.FocusedElement.RaiseEvent(textCompositionEventArgs);
}
}
currentCell.EndEdit();
});
}
}
}
5 comments:
How can i change the content of the cell
I have write the following code (It enter the edit mode, but the content still the same:
currentCell.BeginEdit();
currentCell.Content = new System.Windows.Controls.Button();
currentCell.EndEdit();
Hmm, I would have thought setting the content of the cell should just work. I would need more info, you may be better off posting your question to the XCeed forum - http://forums.xceed.com/forums/ShowForum.aspx?ForumID=40
How do you get around custom Cell Editors?
Hi
Thanks,your article is helping me a lot.
I have only one problem call currentcolumn
Always i am receiving a null value when i do click over the datagrid,right,left,doesn´t matter,a selected row or not doesn´t matter...always null
How can i use the property with that code
void tradesGrid_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
DataGridControl dataGridControl = sender as DataGridControl;
if (dataGridControl != null)
{
Xceed.Wpf.DataGrid.Row row = (Xceed.Wpf.DataGrid.Row)dataGridControl.GetContainerFromItem(dataGridControl.CurrentItem);
Xceed.Wpf.DataGrid.Cell currentCell = row.Cells[dataGridControl.CurrentColumn.Index];
//Xceed.Wpf.DataGrid.Cell currentCell = row.Cells[2];
if (currentCell != null && currentCell.HasContent)
{
Clipboard.SetText(currentCell.Content.ToString());
}
}
}
I´m sure is correct due to i probed it with Xceed.Wpf.DataGrid.Cell currentCell = row.Cells[2] and works fine.
But when i´m trying to use the property CurrentColumn i obtain always a null value.
Why,who knows,someone can tell me how to activate that property correctly ?
Thanks in advance,
Leonardo
To be honest I really don't know! I haven't used the Xceed datagrid for over a year now, and there's been lots of new versions since I wrote this article.
Can I suggest you ask the question on the Xceed forums?
Regards
Neil
Post a Comment