Mac 如何在 NSTableView 中拖放行
How to drag and drop rows in NSTableView in Mac
我注意到一点,即现在我已经使用 NSTableView 获得了一个数据列表,但我的要求是,能够将这些行从一个行位置拖放到另一个行位置。请提出解决此问题的任何建议。提前致谢。
在您的 NSTableViewDataSource
子类中实现 WriteRows
、ValidateDrop
和 AcceptDrop
并注册 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;
}
我注意到一点,即现在我已经使用 NSTableView 获得了一个数据列表,但我的要求是,能够将这些行从一个行位置拖放到另一个行位置。请提出解决此问题的任何建议。提前致谢。
在您的 NSTableViewDataSource
子类中实现 WriteRows
、ValidateDrop
和 AcceptDrop
并注册 Drag/Drop 目标您的 NSTableView
接受。在这种情况下,您只接受来自您自己 NSTableView
.
指定一个名称,该名称将用于在此 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;
}