我有一个WPF Datagrid,我正在实现拖放功能 datagrid有一个“文件”列表,用户可以拖动它们并将文件复制到桌面 这是这样做的:
string[] files = new String[myDataGrid.SelectedItems.Count];
int ix = 0;
foreach (object nextSel in myDataGrid.SelectedItems)
{
files[ix] = ((Song)nextSel).FileLocation;
++ix;
}
string dataFormat = DataFormats.FileDrop;
DataObject dataObject = new DataObject(dataFormat, files);
DragDrop.DoDragDrop(this.myDataGrid, dataObject, DragDropEffects.Copy);
我有两个问题:
1.当我想拖动多个项目时 - 这是一个问题,因为在我选择一对并开始点击其中一个开始拖动之后 - 仅选择该项目并取消选择其他项目。我尝试了here给出的解决方案,但由于某种原因它不起作用
2.我希望在复制后从数据网格中删除拖动的项目。问题是我不知道如何检查文件是否被复制,或者用户是否只是在屏幕上拖动它而不复制它。
我希望你能帮助我解决这些问题 谢谢!
答案 0 :(得分:5)
我认为这就是你要找的东西:
将此代码添加到DataGrid__PreviewMouseLeftButtonDown事件处理程序中:
private void DataGrid_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
this.startingPosition = e.GetPosition(null);
DependencyObject dep = (DependencyObject)e.OriginalSource;
// iteratively traverse the visual tree until get a row or null
while ((dep != null) && !(dep is DataGridRow))
{
dep = VisualTreeHelper.GetParent(dep);
}
//if this is a row (item)
if (dep is DataGridRow)
{
//if the pointed item is already selected do not reselect it, so the previous multi-selection will remain
if (songListDB.SelectedItems.Contains((dep as DataGridRow).Item))
{
// now the drag will drag all selected files
e.Handled = true;
}
}
}
现在,拖延不会改变你的选择。
祝你好运!
我用article来写我的答案
答案 1 :(得分:1)
改进了查找行。 还添加了在不拖动时选择单击的行。 现在,这与其他Microsoft选择器(例如Outlook)完全相同
public TreeDataGrid()
{
Loaded += TreeDataGrid_Loaded;
LoadingRow += new EventHandler<DataGridRowEventArgs>(TreeDataGrid_LoadingRow);
}
#region MultiSelect Drag
object toSelectItemOnMouseLeftButtonUp;
void TreeDataGrid_LoadingRow(object sender, DataGridRowEventArgs e)
{
e.Row.PreviewMouseLeftButtonDown += new MouseButtonEventHandler(Row_PreviewMouseLeftButtonDown);
e.Row.PreviewMouseLeftButtonUp += new MouseButtonEventHandler(Row_PreviewMouseLeftButtonUp);
}
void Row_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
DataGridRow row = (DataGridRow)sender;
toSelectItemOnMouseLeftButtonUp = null; // always clear selecteditem
if (SelectedItems.Contains(row.Item)) //if the pointed item is already selected do not reselect it, so the previous multi-selection will remain
{
e.Handled = true; // this prevents the multiselection from disappearing, BUT datagridcell still gets the event and sets DataGrid's private member _selectionAnchor
toSelectItemOnMouseLeftButtonUp = row.Item; // store our item to select on MouseLeftButtonUp
}
}
void Row_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
DataGridRow row = (DataGridRow)sender;
if (row.Item == toSelectItemOnMouseLeftButtonUp) // check if it's set and concerning the same row
{
if (SelectedItem == toSelectItemOnMouseLeftButtonUp) SelectedItem = null; // if the item is already selected whe need to trigger a change
SelectedItem = toSelectItemOnMouseLeftButtonUp; // this will clear the multi selection, and only select the item we pressed down on
typeof(DataGrid).GetField("_selectionAnchor", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(this, new DataGridCellInfo(row.Item, ColumnFromDisplayIndex(0))); // we need to set this anchor for when we select by pressing shift key
toSelectItemOnMouseLeftButtonUp = null; // handled
}
}
#endregion