【问题标题】:WPF Datagrid drag and drop questionsWPF Datagrid 拖放问题
【发布时间】:2011-08-14 20:47:34
【问题描述】:

我有一个 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.我想在复制后将拖动的项目从数据网格中删除。问题是我不知道如何检查文件是否被复制,或者用户是否只是在屏幕上拖动它而不复制它。

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

【问题讨论】:

    标签: wpf drag-and-drop wpfdatagrid


    【解决方案1】:

    我想这就是你要找的东西:

    将此代码添加到 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 写了我的答案

    【讨论】:

    • 谢谢!正是我想要的 [songListDB? :) ]
    • 这是迄今为止我见过的最简单的解决方案。谢谢。
    【解决方案2】:

    改进了查找行。 在不拖动时还选择单击的行。 现在,它的行为与其他 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-07
      • 1970-01-01
      相关资源
      最近更新 更多