Mac 如何在 NSTableView 中拖放行

How to drag and drop rows in NSTableView in Mac

我注意到一点,即现在我已经使用 NSTableView 获得了一个数据列表,但我的要求是,能够将这些行从一个行位置拖放到另一个行位置。请提出解决此问题的任何建议。提前致谢。

My sample code

在您的 NSTableViewDataSource 子类中实现 WriteRowsValidateDropAcceptDrop 并注册 Drag/Drop 目标您的 NSTableView 接受。在这种情况下,您只接受来自您自己 NSTableView.

的 Drops

指定一个名称,该名称将用于在此 NSTableView 上进行有效的拖动操作:

// Any name can be registered, I find using the class name 
// of the items in the datasource is cleaner than a const string
string DragDropType = typeof(Product).FullName;

为您的NSTableView注册拖动类型:

ProductTable.RegisterForDraggedTypes(new string[] { DragDropType }); 

在您的 NSTableViewDataSource 上实施 drag/drop 方法:

public override bool WriteRows(NSTableView tableView, NSIndexSet rowIndexes, NSPasteboard pboard)
{
    var data = NSKeyedArchiver.ArchivedDataWithRootObject(rowIndexes);
    pboard.DeclareTypes(new string[] { DragDropType }, this);
    pboard.SetDataForType(data, DragDropType);
    return true;
}

public override NSDragOperation ValidateDrop(NSTableView tableView, NSDraggingInfo info, nint row, NSTableViewDropOperation dropOperation)
{
    tableView.SetDropRowDropOperation(row, dropOperation);
    return NSDragOperation.Move;
}

public override bool AcceptDrop(NSTableView tableView, NSDraggingInfo info, nint row, NSTableViewDropOperation dropOperation)
{
    var rowData = info.DraggingPasteboard.GetDataForType(DragDropType);
    if (rowData == null)
        return false;
    var dataArray = NSKeyedUnarchiver.UnarchiveObject(rowData) as NSIndexSet;
    Console.WriteLine($"{dataArray}");
    // Move hack for this example... you need to handle the complete NSIndexSet
    tableView.BeginUpdates();
    var tmpProduct = Products[(int)dataArray.FirstIndex];
    Products.RemoveAt((int)dataArray.FirstIndex);
    if (Products.Count == row - 1)
        Products.Insert((int)row - 1 , tmpProduct);
    else 
        Products.Insert((int)row, tmpProduct);
    tableView.ReloadData();
    tableView.EndUpdates();
    return true;
}