Xamarin Forms如何制作可拖动的列表视图

时间:2014-08-05 19:48:46

标签: listview xamarin.forms draggable

是否可以使用Xamarin表单创建包含可拖动列表项的列表视图?

我在下面的链接中找到了在android中实现的引用,但我不确定如何在Xamarin.Forms中进行此操作,我假设我需要为此添加特定于平台的代码?

How to make a ListView with draggable items?

此外,如下面的Xamarin论坛帖子所示,控件似乎不支持拖放功能,因此需要创建自定义渲染器,但我不太确定从哪里开始

http://forums.xamarin.com/discussion/18114/do-the-xamarin-forms-controls-support-drag-drop-runtime-functionality

2 个答案:

答案 0 :(得分:3)

对于iOS,您可以利用本机UITableView控件的重新排序功能。为ListView创建一个自定义渲染器,告诉iOS您希望所有行都可以移动。让它更新源列表的顺序以匹配用户的操作。

从子类开始。

public class EditListView : ListView { }

然后添加更新ListView.ItemsSource的自定义渲染器以反映更改的订单。此代码假定ItemsSourceList<ListItem>,其中ListItem具有字符串类型的IdName属性。

[assembly: ExportRenderer(typeof(EditListView), typeof(EditListViewRenderer))]
public class EditListViewRenderer : ListViewRenderer
{
    protected override void OnElementChanged(ElementChangedEventArgs<ListView> e)
    {
        base.OnElementChanged(e);

        if (e.NewElement != null) {
            Control.Source = new TableViewSource((List<ListItem>)e.NewElement.ItemsSource);
            Control.Editing = true;
        }
    }

    class TableViewSource : UITableViewSource
    {
        readonly List<ListItem> items;

        public TableViewSource(List<ListItem> items) { this.items = items; }

        public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
        {
            var item = items[indexPath.Row];
            var cell = new UITableViewCell(UITableViewCellStyle.Default, item.Id); // No recycling. If the list is big enough to need recycling, the user won't be very happy about reordering it by hand. :-)
            cell.TextLabel.Text = item.Name;
            return cell;
        }

        public override void MoveRow(UITableView tableView, NSIndexPath sourceIndexPath, NSIndexPath destinationIndexPath)
        {
            int source = sourceIndexPath.Row, dest = destinationIndexPath.Row;
            var movedItem = items[source];
            items.RemoveAt(source);
            if (source > dest) --source;
            items.Insert(dest, movedItem);
        }

        public override nint RowsInSection(UITableView tableview, nint section) => items.Count;
        public override bool CanMoveRow(UITableView tableView, NSIndexPath indexPath) => true;
        public override bool CanEditRow(UITableView tableView, NSIndexPath indexPath) => true; // Only editable rows can be moved.
        public override bool ShouldIndentWhileEditing(UITableView tableView, NSIndexPath indexPath) => false;
        public override UITableViewCellEditingStyle EditingStyleForRow(UITableView tableView, NSIndexPath indexPath) => UITableViewCellEditingStyle.None;
    }
}

答案 1 :(得分:2)

正如你的链接所指出的,它不可能只使用提供的 Xamarin.Forms 控件。

因此,您必须为每个平台实施自定义渲染器

可以在http://developer.xamarin.com/guides/cross-platform/xamarin-forms/custom-renderer/

上找到很棒的教程

在该页面的最底部是我真正建议您浏览的视频,因为它非常有用,可以让您为 Android <编写自己的自定义渲染器类/ strong>和 iOS 。同样的原则适用于 Windows Phone ,所以如果您想要定位它也不应该太难。