答案 0 :(得分:2)
在NSTableViewDataSource
子类实现WriteRows
,ValidateDrop
和AcceptDrop
中,并注册NSTableView
接受的拖放目标。在这种情况下,您只接受自己NSTableView
内的Drop。
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
上实施拖放方法: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;
}