Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add drag-drop item reordering to CollectionView #3767 #3768

Merged
merged 4 commits into from
Feb 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Maui.Controls.Sample.Pages.CollectionViewGalleries.GroupingGalleries;
using Maui.Controls.Sample.Pages.CollectionViewGalleries.HeaderFooterGalleries;
using Maui.Controls.Sample.Pages.CollectionViewGalleries.ItemSizeGalleries;
using Maui.Controls.Sample.Pages.CollectionViewGalleries.ReorderingGalleries;
using Maui.Controls.Sample.Pages.CollectionViewGalleries.ScrollModeGalleries;
using Maui.Controls.Sample.Pages.CollectionViewGalleries.SelectionGalleries;
using Maui.Controls.Sample.Pages.CollectionViewGalleries.SpacingGalleries;
Expand Down Expand Up @@ -42,6 +43,7 @@ public CollectionViewGallery()
GalleryBuilder.NavButton("Selection Galleries", () => new SelectionGallery(), Navigation),
GalleryBuilder.NavButton("Propagation Galleries", () => new PropagationGallery(), Navigation),
GalleryBuilder.NavButton("Grouping Galleries", () => new GroupingGallery(), Navigation),
GalleryBuilder.NavButton("Reordering Galleries", () => new ReorderingGallery(), Navigation),
GalleryBuilder.NavButton("Item Spacing Galleries", () => new ItemsSpacingGallery(), Navigation),
GalleryBuilder.NavButton("Item Size Galleries", () => new ItemsSizeGallery(), Navigation),
GalleryBuilder.NavButton("Scroll Mode Galleries", () => new ScrollModeGallery(), Navigation),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,55 @@ public static DataTemplate SpacingTemplate()
});
}

public static DataTemplate GroupItemTemplate()
{
return new DataTemplate(() =>
{
var templateLayout = new StackLayout();

var label = new Label
{
Margin = new Thickness(5, 0, 0, 0),
};
label.SetBinding(Label.TextProperty, new Binding("Name"));

templateLayout.Children.Add(label);

return templateLayout;
});
}

public static DataTemplate GroupHeaderTemplate()
{
return new DataTemplate(() =>
{
var label = new Label
{
BackgroundColor = Colors.LightGreen,
FontSize = 16,
FontAttributes = FontAttributes.Bold,
};
label.SetBinding(Label.TextProperty, new Binding("Name"));

return label;
});
}

public static DataTemplate GroupFooterTemplate()
{
return new DataTemplate(() =>
{
var label = new Label
{
BackgroundColor = Colors.Orange,
Margin = new Thickness(0, 0, 0, 15),
};
label.SetBinding(Label.TextProperty, new Binding("Count", stringFormat: "Total members: {0:D}"));

return label;
});
}

static void More_Clicked(object sender, EventArgs e)
{
throw new NotImplementedException();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,16 @@ internal class ItemsSourceGenerator : ContentView
{
public event EventHandler<NotifyCollectionChangedEventArgs> CollectionChanged;
readonly ItemsView _cv;
private readonly ItemsSourceType _itemsSourceType;
private ItemsSourceType _itemsSourceType;
readonly Entry _entry;
int _count = 0;

CarouselView carousel => _cv as CarouselView;

public int Count => _count;

public ItemsSourceType ItemsSourceType => _itemsSourceType;

public ItemsSourceGenerator(ItemsView cv, int initialItems = 1000,
ItemsSourceType itemsSourceType = ItemsSourceType.List)
{
Expand Down Expand Up @@ -69,6 +72,12 @@ public ItemsSourceGenerator(ItemsView cv, int initialItems = 1000,
"Legumes.jpg"
};

public void GenerateItems(ItemsSourceType itemsSourceType)
{
_itemsSourceType = itemsSourceType;
GenerateItems();
}

public void GenerateItems()
{
switch (_itemsSourceType)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
using System;
using Microsoft.Maui;
using Microsoft.Maui.Controls;
using Microsoft.Maui.Graphics;
using Maui.Controls.Sample.Pages.CollectionViewGalleries.GroupingGalleries;

namespace Maui.Controls.Sample.Pages.CollectionViewGalleries.ReorderingGalleries
{
internal class GroupedReorderingGallery : ContentPage
{
public GroupedReorderingGallery(IItemsLayout itemsLayout)
{
var layout = new Grid
{
RowDefinitions = new RowDefinitionCollection
{
new RowDefinition { Height = GridLength.Auto },
new RowDefinition { Height = GridLength.Auto },
new RowDefinition { Height = GridLength.Auto },
new RowDefinition { Height = GridLength.Auto },
new RowDefinition { Height = GridLength.Star }
}
};

var canMixGroupsLabel = new Label { Text = "CanMixGroups: ", VerticalTextAlignment = TextAlignment.Center };
var canMixGroupsSwitch = new Switch { IsToggled = false };
var canMixGroupsControl = new StackLayout { Orientation = StackOrientation.Horizontal };
canMixGroupsControl.Children.Add(canMixGroupsLabel);
canMixGroupsControl.Children.Add(canMixGroupsSwitch);

var supportLabel = new Label
{
Text = "Reordering of grouped sources is not supported on Windows!",
FontSize = 24,
FontAttributes = FontAttributes.Bold,
IsVisible = (Device.RuntimePlatform == Device.UWP),
BackgroundColor = Colors.Red
};

var reorderCompletedLabel = new Label
{
Text = "ReorderCompleted (event): NA",
};

var collectionView = new CollectionView
{
ItemsLayout = itemsLayout,
ItemTemplate = ExampleTemplates.GroupItemTemplate(),
GroupHeaderTemplate = ExampleTemplates.GroupHeaderTemplate(),
GroupFooterTemplate = ExampleTemplates.GroupFooterTemplate(),
AutomationId = "collectionview",
IsGrouped = true,
CanReorderItems = true
};
collectionView.SetBinding(ReorderableItemsView.CanMixGroupsProperty, new Binding("IsToggled", BindingMode.OneWay, source: canMixGroupsSwitch));
collectionView.ReorderCompleted += (sender, e) => reorderCompletedLabel.Text = $"ReorderCompleted (event): {DateTime.Now}";

var reloadButton = new Button { Text = "Reload Current Source", AutomationId = "btnReload", HorizontalOptions = LayoutOptions.Start };
reloadButton.Clicked += (sender, e) => ReloadItemsSource(collectionView);

layout.Children.Add(supportLabel);
layout.Children.Add(canMixGroupsControl);
layout.Children.Add(reorderCompletedLabel);
layout.Children.Add(reloadButton);
layout.Children.Add(collectionView);

Grid.SetRow(supportLabel, 0);
Grid.SetRow(canMixGroupsControl, 1);
Grid.SetRow(reorderCompletedLabel, 2);
Grid.SetRow(reloadButton, 3);
Grid.SetRow(collectionView, 4);

Content = layout;

collectionView.ItemsSource = new SuperTeams();
}

void ReloadItemsSource(CollectionView collectionView)
{
var currentSource = collectionView.ItemsSource;
collectionView.ItemsSource = null;
collectionView.ItemsSource = currentSource;
}

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using Microsoft.Maui;
using Microsoft.Maui.Controls;

namespace Maui.Controls.Sample.Pages.CollectionViewGalleries.ReorderingGalleries
{
internal class ReorderingGallery : ContentPage
{
public ReorderingGallery()
{
var descriptionLabel =
new Label { Text = "Reordering Galleries", Margin = new Thickness(2, 2, 2, 2) };

Title = "Reordering Galleries";

Content = new ScrollView
{
Content = new StackLayout
{
Children =
{
descriptionLabel,
GalleryBuilder.NavButton("Vertical List Reordering", () =>
new UngroupedReorderingGallery (LinearItemsLayout.Vertical), Navigation),
GalleryBuilder.NavButton("Horizontal List Reordering", () =>
new UngroupedReorderingGallery (LinearItemsLayout.Horizontal), Navigation),
GalleryBuilder.NavButton("Vertical Grid Reordering", () =>
new UngroupedReorderingGallery (new GridItemsLayout(3, ItemsLayoutOrientation.Vertical)), Navigation),
GalleryBuilder.NavButton("Horizontal Grid Reordering", () =>
new UngroupedReorderingGallery (new GridItemsLayout(3, ItemsLayoutOrientation.Horizontal)), Navigation),
GalleryBuilder.NavButton("Grouped List Reordering", () =>
new GroupedReorderingGallery (LinearItemsLayout.Vertical), Navigation),
GalleryBuilder.NavButton("Grouped Grid Reordering", () =>
new GroupedReorderingGallery (new GridItemsLayout(2, ItemsLayoutOrientation.Vertical)), Navigation)

}
}
};
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
using System;
using System.Collections.Specialized;
using Microsoft.Maui;
using Microsoft.Maui.Controls;
using Maui.Controls.Sample.Pages.CollectionViewGalleries.SpacingGalleries;

namespace Maui.Controls.Sample.Pages.CollectionViewGalleries.ReorderingGalleries
{
internal class UngroupedReorderingGallery : ContentPage
{
public UngroupedReorderingGallery(IItemsLayout itemsLayout)
{
var layout = new Grid
{
RowDefinitions = new RowDefinitionCollection
{
new RowDefinition { Height = GridLength.Auto },
new RowDefinition { Height = GridLength.Auto },
new RowDefinition { Height = GridLength.Auto },
new RowDefinition { Height = GridLength.Auto },
new RowDefinition { Height = GridLength.Auto },
new RowDefinition { Height = GridLength.Star }
}
};

var reorderCompletedLabel = new Label
{
Text = "ReorderCompleted (event): NA",
};

var itemTemplate = ExampleTemplates.SpacingTemplate();

var collectionView = new CollectionView
{
ItemsLayout = itemsLayout,
ItemTemplate = itemTemplate,
AutomationId = "collectionview",
CanReorderItems = true
};
collectionView.ReorderCompleted += (sender, e) => reorderCompletedLabel.Text = $"ReorderCompleted (event): {DateTime.Now}";

var generator = new ItemsSourceGenerator(collectionView, initialItems: 20, itemsSourceType: ItemsSourceType.ObservableCollection);

var itemsSourceTypeSelector = new EnumSelector<ItemsSourceType>(() => generator.ItemsSourceType, sourceType => UpdateItemsSourceType(generator, sourceType, collectionView));

var spacingModifier = new SpacingModifier(collectionView.ItemsLayout, "Update_Spacing");

var reloadButton = new Button { Text = "Reload Current Source", AutomationId = "btnReload", HorizontalOptions = LayoutOptions.Start };
reloadButton.Clicked += (sender,e) => ReloadItemsSource(collectionView);

layout.Children.Add(generator);
layout.Children.Add(itemsSourceTypeSelector);
layout.Children.Add(spacingModifier);
layout.Children.Add(reorderCompletedLabel);
layout.Children.Add(reloadButton);
layout.Children.Add(collectionView);

Grid.SetRow(itemsSourceTypeSelector, 1);
Grid.SetRow(spacingModifier, 2);
Grid.SetRow(reorderCompletedLabel, 3);
Grid.SetRow(reloadButton, 4);
Grid.SetRow(collectionView, 5);

Content = layout;

generator.GenerateItems();
}

void ReloadItemsSource(CollectionView collectionView)
{
var currentSource = collectionView.ItemsSource;
collectionView.ItemsSource = null;
collectionView.ItemsSource = currentSource;
}

async void UpdateItemsSourceType(ItemsSourceGenerator generator, ItemsSourceType itemsSourceType, CollectionView collectionView)
{
generator.GenerateItems(itemsSourceType);

if (Device.RuntimePlatform == Device.UWP && !(collectionView.ItemsSource is INotifyCollectionChanged))
{
await DisplayAlert("Warning!", "Reordering on UWP/WinUI only works with ObservableCollections!", "OK");
}
}
}
}
Loading