Is it possible to create a listview with draggable list items using Xamarin forms?
I have found a reference to this achieved in android in the link below but I'm not sure how I would go about this in Xamarin.Forms, I assume I will need to add platform specific code for this ?
How to make a ListView with draggable items?
Additionally as seen by the below Xamarin forum post it seems that controls dont support drag/drop functionality therefore a custom renderer would need to be created but im not quite sure where to begin
http://forums.xamarin.com/discussion/18114/do-the-xamarin-forms-controls-support-drag-drop-runtime-functionality
For iOS, you can take advantage of the native UITableView
control's reordering functionality. Create a custom renderer for a ListView
that tells iOS that you'd like all rows to be movable. Have it update the source list's order to match the user's actions.
Start with a subclass.
public class EditListView : ListView { }
Then add a custom renderer that updates ListView.ItemsSource
to reflect the changed order. This code assumes ItemsSource
is a List<ListItem>
, where ListItem
has Id
and Name
properties of type string.
[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;
}
}
As pointed out on your link, its not possible just using the supplied Xamarin.Forms controls.
You would therefore have to implement Custom Renderers, for each platform.
A great tutorial can be found on http://developer.xamarin.com/guides/cross-platform/xamarin-forms/custom-renderer/
At the very bottom of that page is a video that I really advise you to go through as it is very informative and should get you into writing your own Custom Renderer classes for Android and iOS. The same principles apply to Windows Phone so if you wanted to target that also it shouldn't be too difficult also.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With