开发者

WPF Datagrid drag and drop questions

I have a WPF Datagrid and I'm implementing drag and drop functionality.

The datagrid has a list of "files" and the user can drag them and copy the file to the desktop.

This is done like this:

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

I have two questions:

1. When I want to drag multiple items- this is a problem because after I select a couple and start clicking on one to start dragging- only that gets selected and the other items get deselected. I tried the solution that is given here but for some reason it doesn't work.

2. I want to remove the dragged item from the datagrid after it is copied. The problem is that I don't know how to check if the file was copied or whether the user just dragged it on the screen without copying it.

I hope you can help me solve these problems.

Thanks!


I think this i what you are looking for:

add this code to the DataGrid__PreviewMouseLeftButtonDown event handler:

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

and now the draging won't change you selection.

Have a good luck!

I used that article to write my answer


Improved on finding the row. Also selecting the clicked row when not dragging is added. This now behaves exactly as other Microsoft selectors (eg 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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜