WPF Datagrid перетаскивать вопросы - PullRequest
4 голосов
/ 15 августа 2011

У меня есть таблица данных WPF, и я реализую функцию перетаскивания.
Сеть данных имеет список «файлов», и пользователь может перетащить их и скопировать файл на рабочий стол.
Это сделанокак это:

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. Когда я хочу перетащить несколько элементов - это проблема, потому что после того, как я выбираю пару и начинаю нажимать на один, чтобы начать перетаскивание - толькокоторый выбирается, а другие элементы отменяются.Я пробовал решение, которое указано здесь , но по какой-то причине оно не работает.
2. Я хочу удалить перетаскиваемый элемент из сетки данных после его копирования.Проблема в том, что я не знаю, как проверить, был ли файл скопирован или пользователь просто перетянул его на экран, не копируя его.

Надеюсь, вы поможете мне решить эти проблемы.
Спасибо!

Ответы [ 2 ]

5 голосов
/ 21 августа 2011

Я думаю, это то, что вы ищете:

добавьте этот код в обработчик событий 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;
        }
    }
}

и теперь перетаскивание не изменит ваш выбор.

Удачи!

Я использовал эту статью , чтобы написать свой ответ

1 голос
/ 09 января 2013

Улучшено нахождение строки. Также выбирается выбранная строка, когда не перетаскивается. Это теперь ведет себя точно так же, как другие селекторы 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
...