2011-08-14 121 views
4

我有一个WPF Datagrid,我正在实现拖放功能。
datagrid有一个“文件”列表,用户可以拖动它们并将文件复制到桌面。
这是这样完成的:WPF 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.我想在复制后从数据网格中删除拖动的项目。问题是我不知道如何检查文件是否被复制,或者用户是否将它拖到屏幕上而不复制它。

我希望你能帮我解决这些问题。
谢谢!

回答

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; 
     } 
    } 
} 

现在draging不会改变你的选择。

祝你好运!

我用article写我的回答

+0

谢谢!正是我想要的[songListDB? :)] – amitairos

+0

正如你可以看到问题解决:) 现在我们有其他人... – Seffix

+1

这是迄今为止我看到的最简单的解决方案。谢谢。 – deloreyk

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