我有一个带有以下定义的WPF DataGrid。
<DataGrid Name="DataGridFoo"
AutoGenerateColumns="False"
ItemsSource="{Binding GridData}"
IsReadOnly="True"
SelectionMode="Extended"
SelectionUnit="CellOrRowHeader">
这允许我让用户选择单元格的“区域”。 DataGrid绑定到一个可观察的集合。 XAML列定义隐藏了一些列,其中一些可见如下:
<DataGridTextColumn Binding="{Binding InvoiceID}"
Header="Invoice ID"
Visibility="Hidden"
Width="Auto"/>
<DataGridTextColumn Binding="{Binding InvoiceNumber}"
Header="Invoice Number"
Visibility="Visible"
Width="Auto"/>
<DataGridTextColumn
Binding="{Binding InvoiceDate, StringFormat=\{0:MM/dd/yy\}}"
Header="Invoice Date"
Visibility="Visible"
Width="Auto"/>
我还为DataGrid定义了一个鼠标右键按钮上下文菜单:
<DataGrid.ContextMenu>
<ContextMenu FontSize="16" Background="#FFE6E9EC">
<MenuItem Header="Contact" Click="Contact_Click" />
<Separator />
<MenuItem Header="Copy" Command="Copy" />
</ContextMenu>
</DataGrid.ContextMenu>
我希望能够将当前选定单元格的副本单击,拖放到外部应用程序中。我正在考虑使用按“Alt键”和鼠标左键单击的组合来启动DragDrop操作。
例如,考虑DataGrid中“不规则”的单元格选择:
我不知道如何处理并对此有几个问题:
1)我覆盖哪些事件,以便/鼠标左键单击不影响当前选定的单元格?
2)如何确定鼠标左键单击是否在所选单元格的区域内发生?我该如何处理数据?
3)一旦我确定了上述内容,下一步是什么?是否将数据复制到剪贴板以便在外部删除中使用?
4)我需要在DataGrid上覆盖哪些事件(如果有)以使其正常工作?
由于
答案 0 :(得分:0)
拖放的基本事件是: events to drag and drop
特别是DragLeave和Drop可以做你想要的。然后,您需要从VM控制(删除/添加)GridData属性以搜索和移动值。 我强烈推荐像Telerik这样的第三方。
答案 1 :(得分:0)
我相信这是你的完整答案。
private void dataGridMaster_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
if(Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift) & e.ChangedButton == MouseButton.Left)
{
DataGrid grid = e.Source as DataGrid;
DataGridCell cell = GetParent<DataGridCell>(e.OriginalSource as DependencyObject);
if(grid != null && cell != null && cell.IsSelected)
{
e.Handled = true;
StartDragAndDrop(grid);
}
}
}
private T GetParent<T>(DependencyObject d) where T:class
{
while (d != null && !(d is T))
{
d = VisualTreeHelper.GetParent(d);
}
return d as T;
}
private void StartDragAndDrop(DataGrid grid)
{
StringBuilder sb = new StringBuilder();
DataRow row = null;
foreach(DataGridCellInfo ci in grid.SelectedCells)
{
DataRowView drv = ci.Item as DataRowView;
string column = ci.Column.Header as string;
if(drv != null && column != null)
{
if(drv.Row != row && row != null)
{
sb.Length--;
sb.AppendLine();
row = drv.Row;
}
else if(row == null)
{
row = drv.Row;
}
sb.Append(drv[column].ToString() + "\t");
}
}
if (sb.Length > 0)
{
sb.Length--;
sb.AppendLine();
}
DragDrop.DoDragDrop(grid, sb.ToString(), DragDropEffects.Copy);
}
在这里你需要按下shift键来发出阻力信号。这需要消除DataGrid中用于选择单元格的单击和拖动的歧义。您可以使用其他一些机制,例如上下文菜单项。
剪贴板是任何拖放操作的关键。您正在做的是将数据放在剪贴板上,以丢弃目标识别的各种格式。在此示例中,仅使用纯文本。但您可能希望创建富文本或HTML或任意数量的其他格式。
您要放在上的外部应用程序必须注册为放置目标。你不能强迫其他应用程序响应drop ...它必须正在倾听它。因此,此示例将适用于Word和Excel。它不适用于记事本。
我相信所有4项都满意: