【问题标题】:Xamarin Forms How to make a draggable listviewXamarin Forms 如何制作可拖动的列表视图
【发布时间】:2014-09-28 14:30:54
【问题描述】:

是否可以使用 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

【问题讨论】:

标签: listview xamarin.forms draggable


【解决方案1】:

对于 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;
    }
}

【讨论】:

    【解决方案2】:

    正如您在链接中指出的那样,仅使用提供的 Xamarin.Forms 控件是不可能的。

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

    可以在http://developer.xamarin.com/guides/cross-platform/xamarin-forms/custom-renderer/找到一个很棒的教程

    在该页面的最底部是一个视频,我真的建议您观看它,因为它提供了非常丰富的信息,应该可以让您为 AndroidCustom Renderer 类/strong> 和 iOS。相同的原则适用于 Windows Phone,所以如果您也想定位它,它也不应该太难。

    【讨论】:

    • 感谢您的链接,请查看教程并尝试实施
    • @ChadBonthuys - 你最终得到这个工作了吗?如果你能发布你的解决方案那就太好了:)
    • @JeremyThompson 我很久以前就遇到过这个问题,从那时起 Xamarin.Forms 已经走了很长一段路。当时,我使用带有向上/向下箭头的自定义视图单元格进行了一个简单的实现,其中 PropertyChangedEventHandler 绑定到列表视图以刷新事件激活时的项目源。从那时起,Xamarin 已经发布了长按事件和更好的触摸手势,所以我确信现在这是可能的,但从那以后我没有重新审视它。这是对可能对您有帮助的链接的参考smartmobidevice.blogspot.co.za/2015/02/…
    猜你喜欢
    • 2016-12-06
    • 1970-01-01
    • 1970-01-01
    • 2017-11-29
    • 1970-01-01
    • 2018-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多