2011-08-14 160 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