Handle ListView reorder with groups (#331)

Handle ListView reorder with groups
This commit is contained in:
Ivan Todorov 2018-10-26 10:12:28 +03:00 коммит произвёл GitHub
Родитель 7f101015b2
Коммит f62131a5a8
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
18 изменённых файлов: 604 добавлений и 84 удалений

Просмотреть файл

@ -131,6 +131,7 @@
<Compile Include="Data\Engine\Groups\Descriptions\CollectionViewGroupDescription.cs" />
<Compile Include="Data\Engine\IncrementalLoading\PlaceholderInfoType.cs" />
<Compile Include="Data\Engine\DataProviders\ViewChangingEventArgs.cs" />
<Compile Include="Data\Engine\ItemReorderPlacement.cs" />
<Compile Include="Data\IDataViewCollection.cs" />
<Compile Include="Data\IncrementalLoading\BatchLoadingEventArgs.cs" />
<Compile Include="Data\IncrementalLoading\BatchLoadingMode.cs" />

Просмотреть файл

@ -260,7 +260,7 @@ namespace Telerik.Data.Core
/// Notify that changes were applied that would alter the data results.
/// Queues an automatic <see cref="Refresh"/>.
/// </summary>
protected void Invalidate()
internal void Invalidate()
{
if (!this.invalidated)
{

Просмотреть файл

@ -0,0 +1,18 @@
namespace Telerik.Data.Core
{
/// <summary>
/// Indicates whether the dragged item should be placed before or after the destination item.
/// </summary>
public enum ItemReorderPlacement
{
/// <summary>
/// The dragged item should be placed before the destination item.
/// </summary>
Before,
/// <summary>
/// The dragged item should be placed after the destination item.
/// </summary>
After
}
}

Просмотреть файл

@ -59,8 +59,11 @@
<Compile Include="DataForm\View\Editors\SegmentedControlCustomEditor.cs" />
<Compile Include="DataForm\View\Editors\SliderCustomEditor.cs" />
<Compile Include="ListView\Data\ListViewDataView.cs" />
<Compile Include="ListView\View\Controls\ListViewGroupHeader.IDragDropElement.cs" />
<Compile Include="ListView\View\Controls\ListViewGroupHeader.Reorder.cs" />
<Compile Include="ListView\View\Controls\ListViewLoadDataUICommand.cs" />
<Compile Include="ListView\View\RadListView.Data.cs" />
<Compile Include="ListView\View\Reorder\ListViewReorderItemsCoordinator.cs" />
<Compile Include="ListView\View\Services\Commands\GroupHeaderTapCommand.cs" />
<Compile Include="ListView\View\Services\Commands\ItemHoldCommand.cs" />
<Compile Include="ListView\View\Services\Commands\ItemHoldContext.cs" />

Просмотреть файл

@ -0,0 +1,109 @@
using Telerik.UI.Xaml.Controls.Data.ListView.View.Controls;
using Telerik.UI.Xaml.Controls.Primitives.DragDrop;
using Windows.Foundation;
using Windows.UI.Xaml.Controls;
namespace Telerik.UI.Xaml.Controls.Data.ListView.Primitives
{
public partial class ListViewGroupHeader : IDragDropElement
{
bool IDragDropElement.SkipHitTest { get; set; }
bool IDragDropElement.CanDrop(DragContext dragContext)
{
return false;
}
bool IDragDropElement.CanStartDrag(DragDropTrigger trigger, object initializeContext)
{
return false;
}
void IDragDropElement.DragEnter(DragContext context)
{
var positionMode = this.Owner.Orientation == Orientation.Vertical ?
DragPositionMode.RailY : DragPositionMode.RailX;
DragDrop.SetDragPositionMode(this, positionMode);
}
void IDragDropElement.DragLeave(DragContext context)
{
}
void IDragDropElement.DragOver(DragContext context)
{
if (context == null)
{
return;
}
var data = context.PayloadData as ReorderItemsDragOperation;
if (data == null)
{
return;
}
var position = context.GetDragPosition(this);
if (!this.ShouldReorder(position, data))
{
return;
}
if (this.Owner.swipedItem == data.Item)
{
this.Owner.ResetActionContent();
}
var newIndex = this.reorderCoordinator.ReorderItem(data.CurrentSourceReorderIndex, this);
data.CurrentSourceReorderIndex = newIndex;
}
DragStartingContext IDragDropElement.DragStarting(DragDropTrigger trigger, object initializeContext)
{
return null;
}
void IDragDropElement.OnDragDropComplete(DragCompleteContext dragContext)
{
}
void IDragDropElement.OnDragging(DragContext dragContext)
{
}
void IDragDropElement.OnDragVisualCleared(DragCompleteContext dragContext)
{
}
void IDragDropElement.OnDrop(DragContext dragContext)
{
}
private bool ShouldReorder(Point position, ReorderItemsDragOperation data)
{
if (this.reorderCoordinator == null || data.CurrentSourceReorderIndex == 0)
{
return false;
}
var sourceElement = this.reorderCoordinator.Host.ElementAt(data.CurrentSourceReorderIndex);
if (sourceElement == null)
{
return false;
}
var startPosition = this.Owner.Orientation == Orientation.Horizontal ? position.X : position.Y;
var itemLength = this.Owner.Orientation == Orientation.Horizontal ? this.ActualWidth : this.ActualHeight;
return (startPosition >= itemLength / 2 + DragInitializer.DefaultStartTreshold &&
startPosition <= itemLength && this.logicalIndex > data.CurrentSourceReorderIndex) ||
(startPosition <= itemLength / 2 - DragInitializer.DefaultStartTreshold &&
startPosition >= 0 && this.logicalIndex < data.CurrentSourceReorderIndex);
}
}
}

Просмотреть файл

@ -0,0 +1,66 @@
using Telerik.UI.Xaml.Controls.Primitives.DragDrop.Reorder;
using Windows.Foundation;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
namespace Telerik.UI.Xaml.Controls.Data.ListView.Primitives
{
public partial class ListViewGroupHeader : IReorderItem
{
private ReorderItemsCoordinator reorderCoordinator;
private int logicalIndex;
DependencyObject IReorderItem.Visual
{
get
{
return this;
}
}
int IReorderItem.LogicalIndex
{
get
{
return this.logicalIndex;
}
set
{
this.logicalIndex = value;
}
}
Point IReorderItem.ArrangePosition
{
get
{
return new Point(Canvas.GetLeft(this), Canvas.GetTop(this));
}
set
{
Canvas.SetLeft(this, value.X);
Canvas.SetTop(this, value.Y);
}
}
Size IReorderItem.ActualSize
{
get
{
return this.RenderSize;
}
}
ReorderItemsCoordinator IReorderItem.Coordinator
{
get
{
return this.reorderCoordinator;
}
set
{
this.reorderCoordinator = value;
}
}
}
}

Просмотреть файл

@ -8,7 +8,7 @@ namespace Telerik.UI.Xaml.Controls.Data.ListView.Primitives
/// <summary>
/// Allows a user to view a header and expand that header to see further details, or to collapse a section up to a header.
/// </summary>
public class ListViewGroupHeader : RadContentControl, IArrangeChild
public partial class ListViewGroupHeader : RadContentControl, IArrangeChild
{
/// <summary>
/// Identifies the IsExpanded dependency property.

Просмотреть файл

@ -38,6 +38,12 @@ namespace Telerik.UI.Xaml.Controls.Data.ListView.View.Controls
this.owner.visualStateService.RegisterDataLoadingListener(loadDataControl);
}
var reorderItem = element.Container as IReorderItem;
if (reorderItem != null)
{
reorderItem.LogicalIndex = element.ItemInfo.Id;
}
var listItem = element.Container as RadListViewItem;
if (listItem != null)
{
@ -45,9 +51,6 @@ namespace Telerik.UI.Xaml.Controls.Data.ListView.View.Controls
this.owner.PrepareContainerForItem(listItem, element.ItemInfo.Item);
listItem.PrepareSwipeDragHandles();
var reorderItem = listItem as IReorderItem;
reorderItem.LogicalIndex = element.ItemInfo.Id;
this.owner.PrepareReorderItem(listItem);
}
@ -74,6 +77,7 @@ namespace Telerik.UI.Xaml.Controls.Data.ListView.View.Controls
groupHeader.IsExpanded = context.IsExpanded;
this.owner.PrepareContainerForGroupHeader(groupHeader, context);
this.owner.PrepareReorderItem(groupHeader);
}
}
@ -101,6 +105,7 @@ namespace Telerik.UI.Xaml.Controls.Data.ListView.View.Controls
item.ArrangeSize.Height = 0;
item.ArrangeSize.Width = 0;
this.owner.CleanupReorderItem(item);
this.owner.ClearContainerForGroupHeader(item);
}
}

Просмотреть файл

@ -1,4 +1,5 @@
using System;
using Telerik.Data.Core;
using Telerik.UI.Xaml.Controls.Data.ListView.Commands;
using Telerik.UI.Xaml.Controls.Data.ListView.View.Controls;
using Telerik.UI.Xaml.Controls.Primitives.DragDrop;
@ -26,18 +27,18 @@ namespace Telerik.UI.Xaml.Controls.Data.ListView
{
if (trigger == DragDropTrigger.MouseDrag && !this.IsHandleEnabled)
{
return this.ListView.IsItemReorderEnabled && this.listView.GroupDescriptors.Count == 0;
return this.ListView.IsItemReorderEnabled;
}
if (trigger == DragDropTrigger.Hold)
{
return this.ListView.IsItemReorderEnabled && this.ListView.GroupDescriptors.Count == 0 && !this.IsHandleEnabled;
return this.ListView.IsItemReorderEnabled && !this.IsHandleEnabled;
}
else
{
if (this.isHandleEnabled && initializeContext == this.reorderHandle)
{
return this.ListView.IsItemReorderEnabled && this.ListView.GroupDescriptors.Count == 0 && this.IsHandleEnabled;
return this.ListView.IsItemReorderEnabled && this.IsHandleEnabled;
}
return this.ListView.IsActionOnSwipeEnabled && !(this.ListView.ReorderMode == ListViewReorderMode.Handle && this.ListView.IsItemReorderEnabled == true);
@ -265,8 +266,45 @@ namespace Telerik.UI.Xaml.Controls.Data.ListView
{
this.FinalizeReorder(context);
object destinationDataItem = this.GetDestinationDataItem(data.CurrentSourceReorderIndex);
bool isExecuted = this.ListView.commandService.ExecuteCommand(CommandId.ItemReorderComplete, new ItemReorderCompleteContext(data.Data, destinationDataItem, this));
var dataItem = data.Data;
var destinationDataItem = this.GetDestinationDataItem(data.CurrentSourceReorderIndex);
IDataGroup dataGroup = null;
IDataGroup destinationDataGroup = null;
if (this.listView.GroupDescriptors.Count > 0)
{
dataGroup = this.listView.Model.FindItemParentGroup(dataItem);
destinationDataGroup = this.listView.Model.FindItemParentGroup(destinationDataItem);
}
ItemReorderPlacement placement;
if (data.InitialSourceIndex < data.CurrentSourceReorderIndex)
{
placement = ItemReorderPlacement.After;
}
else
{
placement = ItemReorderPlacement.Before;
}
var commandContext = new ItemReorderCompleteContext(dataItem, dataGroup, destinationDataItem, destinationDataGroup, placement);
var isExecuted = this.ListView.commandService.ExecuteCommand(CommandId.ItemReorderComplete, commandContext);
if (isExecuted)
{
// TODO: Data provider does not handle well reordering of items in groups.
// Remove this workaround once we fix the reordering in the data provider.
if (this.listView.GroupDescriptors.Count > 0)
{
this.listView.updateService.RegisterUpdate((int)UpdateFlags.AffectsData);
}
}
else
{
this.reorderCoordinator.CancelReorderOperation(this, data.InitialSourceIndex);
}
}
else
{

Просмотреть файл

@ -113,7 +113,21 @@ namespace Telerik.UI.Xaml.Controls.Data.ListView
(dragVisual as IDragDropElement).SkipHitTest = true;
DragDrop.SetDragPositionMode(this, this.ListView.Orientation == Orientation.Vertical ? DragPositionMode.RailY : DragPositionMode.RailX);
var dragPositionMode = DragPositionMode.Free;
if (this.ListView.LayoutDefinition is StackLayoutDefinition)
{
if (this.ListView.Orientation == Orientation.Vertical)
{
dragPositionMode = DragPositionMode.RailY;
}
else
{
dragPositionMode = DragPositionMode.RailX;
}
}
DragDrop.SetDragPositionMode(this, dragPositionMode);
this.Opacity = 0.0;
@ -136,11 +150,16 @@ namespace Telerik.UI.Xaml.Controls.Data.ListView
{
this.ListView.DragBehavior.OnDragDropCompleted(this, context.DragSuccessful);
var itemReordered = context.DragSuccessful;
if (!itemReordered && this.reorderCoordinator != null)
if (this.reorderCoordinator != null)
{
this.reorderCoordinator.CancelReorderOperation(this, data.InitialSourceIndex);
if (context.DragSuccessful)
{
this.reorderCoordinator.CommitReorderOperation(data.InitialSourceIndex, data.CurrentSourceReorderIndex);
}
else
{
this.reorderCoordinator.CancelReorderOperation(this, data.InitialSourceIndex);
}
}
}
}

Просмотреть файл

@ -68,7 +68,7 @@ namespace Telerik.UI.Xaml.Controls.Data
{
}
internal void PrepareReorderItem(RadListViewItem reorderItem)
internal void PrepareReorderItem(DependencyObject reorderItem)
{
if (reorderItem != null)
{
@ -77,7 +77,7 @@ namespace Telerik.UI.Xaml.Controls.Data
}
}
internal void CleanupReorderItem(RadListViewItem reorderItem)
internal void CleanupReorderItem(DependencyObject reorderItem)
{
if (reorderItem != null)
{
@ -106,7 +106,7 @@ namespace Telerik.UI.Xaml.Controls.Data
private void InitializeReorder()
{
this.reorderCoordinator = new ReorderItemsCoordinator(this);
this.reorderCoordinator = new ListViewReorderItemsCoordinator(this);
}
}
}

Просмотреть файл

@ -0,0 +1,99 @@
using System;
using System.Linq;
using Telerik.UI.Xaml.Controls.Data.ListView;
using Telerik.UI.Xaml.Controls.Primitives.DragDrop.Reorder;
using Windows.Foundation;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
namespace Telerik.UI.Xaml.Controls.Data
{
internal class ListViewReorderItemsCoordinator : ReorderItemsCoordinator
{
public ListViewReorderItemsCoordinator(IReorderItemsHost host)
: base(host)
{
}
protected override void UpdatePositionAndIndices(IReorderItem source, IReorderItem destination)
{
var listView = (RadListView)this.Host;
if (listView.GroupDescriptors.Count == 0 || listView.LayoutDefinition is StackLayoutDefinition)
{
base.UpdatePositionAndIndices(source, destination);
return;
}
var sourceIndex = source.LogicalIndex;
var destinationIndex = destination.LogicalIndex;
var childrenPanel = listView.childrenPanel;
var reorderItems = childrenPanel.Children.OfType<IReorderItem>()
.OrderBy(reorderItem => reorderItem.LogicalIndex).ToArray();
var firstItem = reorderItems[0];
var layoutItem = (IArrangeChild)firstItem;
var layoutSlot = layoutItem.LayoutSlot;
var arrangePosition = firstItem.ArrangePosition;
for (int logicalIndex = 0; logicalIndex < reorderItems.Length; logicalIndex++)
{
IReorderItem reorderItem;
if (logicalIndex == destinationIndex)
{
reorderItem = reorderItems[sourceIndex];
}
else if (logicalIndex >= sourceIndex && logicalIndex < destinationIndex)
{
reorderItem = reorderItems[logicalIndex + 1];
}
else if (logicalIndex > destinationIndex && logicalIndex <= sourceIndex)
{
reorderItem = reorderItems[logicalIndex - 1];
}
else
{
reorderItem = reorderItems[logicalIndex];
}
reorderItem.LogicalIndex = logicalIndex;
var actualSize = reorderItem.ActualSize;
if (listView.Orientation == Orientation.Vertical)
{
if (arrangePosition.X + actualSize.Width > childrenPanel.ActualWidth)
{
arrangePosition.X = 0;
arrangePosition.Y += layoutSlot.Height;
}
}
else
{
if (arrangePosition.Y + actualSize.Height > childrenPanel.ActualHeight)
{
arrangePosition.Y = 0;
arrangePosition.X += layoutSlot.Width;
}
}
if (arrangePosition != reorderItem.ArrangePosition)
{
this.AnimateItem(source, reorderItem, arrangePosition);
}
if (listView.Orientation == Orientation.Vertical)
{
arrangePosition.X += actualSize.Width;
}
else
{
arrangePosition.Y += actualSize.Height;
}
layoutItem = (IArrangeChild)reorderItem;
layoutSlot = layoutItem.LayoutSlot;
}
}
}
}

Просмотреть файл

@ -1,4 +1,6 @@
namespace Telerik.UI.Xaml.Controls.Data.ListView.Commands
using Telerik.Data.Core;
namespace Telerik.UI.Xaml.Controls.Data.ListView.Commands
{
/// <summary>
/// The context that is passed as a parameter to the <see cref="ItemReorderCompleteCommand"/>.
@ -8,11 +10,21 @@
/// <summary>
/// Initializes a new instance of the <see cref="ItemReorderCompleteContext"/> class.
/// </summary>
public ItemReorderCompleteContext(object dataItem, object destinationItem, RadListViewItem container)
public ItemReorderCompleteContext(object dataItem, object destinationItem, ItemReorderPlacement placement)
: this(dataItem, null, destinationItem, null, placement)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="ItemReorderCompleteContext"/> class.
/// </summary>
public ItemReorderCompleteContext(object dataItem, IDataGroup dataGroup, object destinationItem, IDataGroup destinationGroup, ItemReorderPlacement placement)
{
this.Item = dataItem;
this.Group = dataGroup;
this.DestinationItem = destinationItem;
this.Container = container;
this.DestinationGroup = destinationGroup;
this.Placement = placement;
}
/// <summary>
@ -20,11 +32,24 @@
/// </summary>
public object Item { get; set; }
/// <summary>
/// Gets or sets the data group that corresponds to the <see cref="RadListViewItem"/> that is being interacted with.
/// </summary>
public IDataGroup Group { get; set; }
/// <summary>
/// Gets or sets the data item that corresponds to the location where the dragged item has been released.
/// </summary>
public object DestinationItem { get; set; }
internal RadListViewItem Container { get; set; }
/// <summary>
/// Gets or sets the data group that corresponds to the location where the dragged item has been released.
/// </summary>
public IDataGroup DestinationGroup { get; set; }
/// <summary>
/// Gets or sets a value indicating whether the dragged item should be placed before or after the destination item.
/// </summary>
public ItemReorderPlacement Placement { get; set; }
}
}

Просмотреть файл

@ -1,8 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Foundation;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Media.Animation;
@ -20,11 +17,8 @@ namespace Telerik.UI.Xaml.Controls.Primitives.DragDrop.Reorder
public ReorderItemsCoordinator(IReorderItemsHost host)
{
this.Host = host;
this.ReorderWithAnimation = true;
}
internal bool ReorderWithAnimation { get; set; }
internal IReorderItemsHost Host
{
get;
@ -71,11 +65,17 @@ namespace Telerik.UI.Xaml.Controls.Primitives.DragDrop.Reorder
this.UpdatePositionAndIndices(sourceItem, destinationItem);
}
protected virtual void AnimateItem(IReorderItem item, Point position, Action actionCompleted)
protected void AnimateItem(IReorderItem source, IReorderItem destination, Point position)
{
var dragPositionMode = DragDrop.GetDragPositionMode(item.Visual);
var dragPositionMode = DragDrop.GetDragPositionMode(destination.Visual);
Storyboard b = new Storyboard();
Action actionCompleted = () =>
{
destination.ArrangePosition = position;
this.animatingElements.Remove(destination);
this.Host.OnItemsReordered(source, destination);
};
this.runningAnimations.Add(b, actionCompleted);
@ -86,7 +86,7 @@ namespace Telerik.UI.Xaml.Controls.Primitives.DragDrop.Reorder
topAnimation.EasingFunction = new QuadraticEase() { EasingMode = EasingMode.EaseIn };
topAnimation.To = position.Y;
Storyboard.SetTargetProperty(topAnimation, "(Canvas.Top)");
Storyboard.SetTarget(topAnimation, item.Visual);
Storyboard.SetTarget(topAnimation, destination.Visual);
b.Children.Add(topAnimation);
}
@ -97,7 +97,7 @@ namespace Telerik.UI.Xaml.Controls.Primitives.DragDrop.Reorder
leftAnimation.EasingFunction = new QuadraticEase() { EasingMode = EasingMode.EaseIn };
leftAnimation.To = position.X;
Storyboard.SetTargetProperty(leftAnimation, "(Canvas.Left)");
Storyboard.SetTarget(leftAnimation, item.Visual);
Storyboard.SetTarget(leftAnimation, destination.Visual);
b.Children.Add(leftAnimation);
}
@ -110,46 +110,7 @@ namespace Telerik.UI.Xaml.Controls.Primitives.DragDrop.Reorder
b.Begin();
}
private static Point GetRearangePosition(IReorderItem targetItem, IReorderItem adjasentItem)
{
Point position;
if (targetItem.LogicalIndex > adjasentItem.LogicalIndex)
{
position = adjasentItem.ArrangePosition;
}
else
{
double x = -1;
double y = -1;
var dragPositionMode = DragDrop.GetDragPositionMode(targetItem.Visual);
if (dragPositionMode == DragPositionMode.RailY || dragPositionMode == DragPositionMode.Free)
{
x = adjasentItem.ArrangePosition.X;
y = adjasentItem.ArrangePosition.Y + adjasentItem.ActualSize.Height - targetItem.ActualSize.Height;
}
if (dragPositionMode == DragPositionMode.RailX || dragPositionMode == DragPositionMode.Free)
{
x = adjasentItem.ArrangePosition.X + adjasentItem.ActualSize.Width - targetItem.ActualSize.Width;
y = adjasentItem.ArrangePosition.Y;
}
position = new Point(x, y);
}
return position;
}
private void ReorderItems(IReorderItem source, IReorderItem destination)
{
if (source != destination && !this.animatingElements.Contains(destination) && !this.animatingElements.Contains(source))
{
this.UpdatePositionAndIndices(source, destination);
}
}
private void UpdatePositionAndIndices(IReorderItem source, IReorderItem destination)
protected virtual void UpdatePositionAndIndices(IReorderItem source, IReorderItem destination)
{
var step = source.LogicalIndex < destination.LogicalIndex ? 1 : -1;
@ -167,29 +128,51 @@ namespace Telerik.UI.Xaml.Controls.Primitives.DragDrop.Reorder
this.animatingElements.Add(currentDestinationItem);
var destinationPosition = ReorderItemsCoordinator.GetRearangePosition(currentDestinationItem, source);
source.ArrangePosition = ReorderItemsCoordinator.GetRearangePosition(source, currentDestinationItem);
var destinationPosition = GetRearrangePosition(currentDestinationItem, source);
source.ArrangePosition = GetRearrangePosition(source, currentDestinationItem);
var index = source.LogicalIndex;
source.LogicalIndex = currentDestinationItem.LogicalIndex;
currentDestinationItem.LogicalIndex = index;
Action moveCompletedAction = () =>
{
currentDestinationItem.ArrangePosition = destinationPosition;
this.animatingElements.Remove(currentDestinationItem);
this.Host.OnItemsReordered(source, currentDestinationItem);
};
this.AnimateItem(source, currentDestinationItem, destinationPosition);
}
}
if (this.ReorderWithAnimation)
private static Point GetRearrangePosition(IReorderItem targetItem, IReorderItem adjacentItem)
{
var position = targetItem.ArrangePosition;
var dragPositionMode = DragDrop.GetDragPositionMode(targetItem.Visual);
if (dragPositionMode == DragPositionMode.RailY || dragPositionMode == DragPositionMode.Free)
{
position.Y = adjacentItem.ArrangePosition.Y;
if (targetItem.LogicalIndex < adjacentItem.LogicalIndex)
{
this.AnimateItem(currentDestinationItem, destinationPosition, moveCompletedAction);
position.Y += adjacentItem.ActualSize.Height - targetItem.ActualSize.Height;
}
else
}
if (dragPositionMode == DragPositionMode.RailX || dragPositionMode == DragPositionMode.Free)
{
position.X = adjacentItem.ArrangePosition.X;
if (targetItem.LogicalIndex < adjacentItem.LogicalIndex)
{
moveCompletedAction();
position.X += adjacentItem.ActualSize.Width - targetItem.ActualSize.Width;
}
}
return position;
}
private void ReorderItems(IReorderItem source, IReorderItem destination)
{
if (source != destination && !this.animatingElements.Contains(destination) && !this.animatingElements.Contains(source))
{
this.UpdatePositionAndIndices(source, destination);
}
}
}
}

Просмотреть файл

@ -88,6 +88,7 @@
<Example DisplayName="Pull to Refresh" ClassName="SDKExamples.UWP.Listview.PullToRefresh" />
<Example DisplayName="Grouping" ClassName="SDKExamples.UWP.Listview.Grouping" />
<Example DisplayName="Reorder" ClassName="SDKExamples.UWP.Listview.Reorder" />
<Example DisplayName="Reorder with Groups" ClassName="SDKExamples.UWP.Listview.ReorderWithGroups" />
<Example DisplayName="Load on Demand" ClassName="SDKExamples.UWP.Listview.LoadOnDemand" />
<Example DisplayName="Filtering" ClassName="SDKExamples.UWP.Listview.Filtering" />
<Example DisplayName="Item Animations" ClassName="SDKExamples.UWP.Listview.ItemAnimations" />

Просмотреть файл

@ -0,0 +1,33 @@
<local:ExamplePageBase x:Class="SDKExamples.UWP.Listview.ReorderWithGroups"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:SDKExamples.UWP"
xmlns:data="using:Telerik.UI.Xaml.Controls.Data"
xmlns:dataCore="using:Telerik.Data.Core"
xmlns:example="using:SDKExamples.UWP.Listview"
x:Name="page">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock Text="{Binding Title, ElementName=page}"
Style="{StaticResource ExampleHeaderTextBlockStyle}" />
<data:RadListView Grid.Row="1"
IsItemReorderEnabled="True"
ReorderMode="Default"
ItemsSource="{Binding Items}">
<data:RadListView.Commands>
<example:ListViewGroupReorderCommand Id="ItemReorderComplete" />
</data:RadListView.Commands>
<data:RadListView.GroupDescriptors>
<dataCore:PropertyGroupDescriptor PropertyName="Category" />
</data:RadListView.GroupDescriptors>
<data:RadListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" />
</DataTemplate>
</data:RadListView.ItemTemplate>
</data:RadListView>
</Grid>
</local:ExamplePageBase>

Просмотреть файл

@ -0,0 +1,113 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using Telerik.Data.Core;
using Telerik.UI.Xaml.Controls.Data.ListView.Commands;
namespace SDKExamples.UWP.Listview
{
public sealed partial class ReorderWithGroups : ExamplePageBase
{
public ReorderWithGroups()
{
this.InitializeComponent();
this.DataContext = new ViewModel();
}
public class ViewModel
{
public ObservableCollection<Item> Items { get; }
public ViewModel()
{
this.Items = new ObservableCollection<Item>();
for (int index = 0; index < 100; index++)
{
var item = new Item
{
Category = $"Category {index / 10}",
Name = $"Item {index}"
};
this.Items.Add(item);
}
}
}
public class Item : INotifyPropertyChanged
{
private string category;
private string name;
public string Category
{
get
{
return this.category;
}
set
{
if (this.category != value)
{
this.category = value;
this.OnPropertyChanged();
}
}
}
public string Name
{
get
{
return this.name;
}
set
{
if (this.name != value)
{
this.name = value;
this.OnPropertyChanged();
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
public class ListViewGroupReorderCommand : ListViewCommand
{
public override bool CanExecute(object parameter)
{
return true;
}
public override void Execute(object parameter)
{
var items = (IList<ReorderWithGroups.Item>)this.Owner.ItemsSource;
var context = (ItemReorderCompleteContext)parameter;
var sourceItem = (ReorderWithGroups.Item)context.Item;
items.Remove(sourceItem);
var destinationItem = (ReorderWithGroups.Item)context.DestinationItem;
var destinationGroup = context.DestinationGroup;
var destinationIndex = items.IndexOf(destinationItem);
if (context.Placement == ItemReorderPlacement.After)
{
destinationIndex++;
}
sourceItem.Category = (string)destinationGroup.Key;
items.Insert(destinationIndex, sourceItem);
}
}
}

Просмотреть файл

@ -355,6 +355,9 @@
<Compile Include="Examples\ListView\Reorder.xaml.cs">
<DependentUpon>Reorder.xaml</DependentUpon>
</Compile>
<Compile Include="Examples\ListView\ReorderWithGroups.xaml.cs">
<DependentUpon>ReorderWithGroups.xaml</DependentUpon>
</Compile>
<Compile Include="Examples\ListView\ScrollIndexIntoView.xaml.cs">
<DependentUpon>ScrollIndexIntoView.xaml</DependentUpon>
</Compile>
@ -789,6 +792,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Examples\ListView\ReorderWithGroups.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Examples\ListView\ScrollIndexIntoView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>