diff --git a/CHANGELOG.md b/CHANGELOG.md index b6d48668..02d508f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ > - Added BeginPanning, UpdatePanning, EndPanning, CancelPanning and AllowPanningCancellation to NodifyEditor > - Added UpdateCuttingLine to NodifyEditor > - Added BeginSelecting, UpdateSelection, EndSelecting, CancelSelecting and AllowSelectionCancellation to NodifyEditor +> - Added IsDragging, BeginDragging, UpdateDragging, EndDragging and CancelDragging to NodifyEditor > - Bugfixes: #### **Version 6.6.0** diff --git a/Nodify/Helpers/PushItemsStrategy.cs b/Nodify/Helpers/PushItemsStrategy.cs index 9701c822..6ab05361 100644 --- a/Nodify/Helpers/PushItemsStrategy.cs +++ b/Nodify/Helpers/PushItemsStrategy.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Diagnostics; using System.Linq; using System.Windows; @@ -12,12 +11,11 @@ internal interface IPushStrategy Rect Push(Vector amount); Rect End(); Rect Cancel(); - Rect OnViewportChanged(); + Rect GetPushedArea(); } internal abstract class BasePushStrategy : IPushStrategy { - private IDraggingStrategy? _draggingStrategy; private const double _minOffset = 2; private double _actualOffset; private double _initialPosition; @@ -33,7 +31,7 @@ public BasePushStrategy(NodifyEditor editor) public Rect Start(Point position) { var containers = GetFilteredContainers(position); - _draggingStrategy = Editor.CreateDraggingStrategy(containers); + Editor.BeginDragging(containers); _initialPosition = GetInitialPosition(position); _actualOffset = 0; @@ -43,10 +41,8 @@ public Rect Start(Point position) public Rect Push(Vector amount) { - Debug.Assert(_draggingStrategy != null); - var offset = GetPushOffset(amount); - _draggingStrategy!.Update(offset); + Editor.UpdateDragging(offset); _actualOffset += offset.X; _actualOffset += offset.Y; @@ -59,15 +55,13 @@ public Rect Push(Vector amount) public Rect End() { - Debug.Assert(_draggingStrategy != null); - _draggingStrategy!.End(); + Editor.EndDragging(); return new Rect(); } public Rect Cancel() { - Debug.Assert(_draggingStrategy != null); - _draggingStrategy!.Abort(); + Editor.CancelDragging(); return new Rect(); } @@ -75,7 +69,7 @@ public Rect Cancel() protected abstract double GetInitialPosition(Point position); protected abstract Vector GetPushOffset(Vector offset); protected abstract Rect CalculatePushedArea(double position, double offset); - public abstract Rect OnViewportChanged(); + public abstract Rect GetPushedArea(); } internal sealed class HorizontalPushStrategy : BasePushStrategy @@ -96,7 +90,7 @@ protected override Vector GetPushOffset(Vector offset) protected override Rect CalculatePushedArea(double position, double offset) => new Rect(position, Editor.ViewportLocation.Y - OffscreenOffset, offset, Editor.ViewportSize.Height + OffscreenOffset * 2); - public override Rect OnViewportChanged() + public override Rect GetPushedArea() => CalculatePushedArea(Editor.PushedArea.X, Editor.PushedArea.Width); } @@ -118,7 +112,7 @@ protected override Vector GetPushOffset(Vector offset) protected override Rect CalculatePushedArea(double position, double offset) => new Rect(Editor.ViewportLocation.X - OffscreenOffset, position, Editor.ViewportSize.Width + OffscreenOffset * 2, offset); - public override Rect OnViewportChanged() + public override Rect GetPushedArea() => CalculatePushedArea(Editor.PushedArea.Y, Editor.PushedArea.Height); } } diff --git a/Nodify/ItemContainer.cs b/Nodify/ItemContainer.cs index 93386c80..7b855afb 100644 --- a/Nodify/ItemContainer.cs +++ b/Nodify/ItemContainer.cs @@ -25,12 +25,12 @@ public class ItemContainer : ContentControl, INodifyCanvasItem public static readonly DependencyProperty SelectedBorderThicknessProperty = DependencyProperty.Register(nameof(SelectedBorderThickness), typeof(Thickness), typeof(ItemContainer), new FrameworkPropertyMetadata(BoxValue.Thickness2)); public static readonly DependencyProperty IsSelectableProperty = DependencyProperty.Register(nameof(IsSelectable), typeof(bool), typeof(ItemContainer), new FrameworkPropertyMetadata(BoxValue.True)); public static readonly DependencyProperty IsSelectedProperty = Selector.IsSelectedProperty.AddOwner(typeof(ItemContainer), new FrameworkPropertyMetadata(BoxValue.False, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnIsSelectedChanged)); - public static readonly DependencyPropertyKey IsPreviewingSelectionPropertyKey = DependencyProperty.RegisterReadOnly(nameof(IsPreviewingSelection), typeof(bool?), typeof(ItemContainer), new FrameworkPropertyMetadata(null)); + protected static readonly DependencyPropertyKey IsPreviewingSelectionPropertyKey = DependencyProperty.RegisterReadOnly(nameof(IsPreviewingSelection), typeof(bool?), typeof(ItemContainer), new FrameworkPropertyMetadata(null)); public static readonly DependencyProperty IsPreviewingSelectionProperty = IsPreviewingSelectionPropertyKey.DependencyProperty; public static readonly DependencyProperty LocationProperty = DependencyProperty.Register(nameof(Location), typeof(Point), typeof(ItemContainer), new FrameworkPropertyMetadata(BoxValue.Point, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnLocationChanged)); public static readonly DependencyProperty ActualSizeProperty = DependencyProperty.Register(nameof(ActualSize), typeof(Size), typeof(ItemContainer), new FrameworkPropertyMetadata(BoxValue.Size)); public static readonly DependencyProperty DesiredSizeForSelectionProperty = DependencyProperty.Register(nameof(DesiredSizeForSelection), typeof(Size?), typeof(ItemContainer), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.NotDataBindable)); - public static readonly DependencyPropertyKey IsPreviewingLocationPropertyKey = DependencyProperty.RegisterReadOnly(nameof(IsPreviewingLocation), typeof(bool), typeof(ItemContainer), new FrameworkPropertyMetadata(BoxValue.False)); + private static readonly DependencyPropertyKey IsPreviewingLocationPropertyKey = DependencyProperty.RegisterReadOnly(nameof(IsPreviewingLocation), typeof(bool), typeof(ItemContainer), new FrameworkPropertyMetadata(BoxValue.False)); public static readonly DependencyProperty IsPreviewingLocationProperty = IsPreviewingLocationPropertyKey.DependencyProperty; public static readonly DependencyProperty IsDraggableProperty = DependencyProperty.Register(nameof(IsDraggable), typeof(bool), typeof(ItemContainer), new FrameworkPropertyMetadata(BoxValue.True)); diff --git a/Nodify/Nodes/Node.cs b/Nodify/Nodes/Node.cs index b1661580..857865ba 100644 --- a/Nodify/Nodes/Node.cs +++ b/Nodify/Nodes/Node.cs @@ -25,7 +25,7 @@ public class Node : HeaderedContentControl public static readonly DependencyProperty FooterProperty = DependencyProperty.Register(nameof(Footer), typeof(object), typeof(Node), new FrameworkPropertyMetadata(OnFooterChanged)); public static readonly DependencyProperty FooterTemplateProperty = DependencyProperty.Register(nameof(FooterTemplate), typeof(DataTemplate), typeof(Node)); public static readonly DependencyProperty InputConnectorTemplateProperty = DependencyProperty.Register(nameof(InputConnectorTemplate), typeof(DataTemplate), typeof(Node)); - protected internal static readonly DependencyPropertyKey HasFooterPropertyKey = DependencyProperty.RegisterReadOnly(nameof(HasFooter), typeof(bool), typeof(Node), new FrameworkPropertyMetadata(BoxValue.False)); + protected static readonly DependencyPropertyKey HasFooterPropertyKey = DependencyProperty.RegisterReadOnly(nameof(HasFooter), typeof(bool), typeof(Node), new FrameworkPropertyMetadata(BoxValue.False)); public static readonly DependencyProperty HasFooterProperty = HasFooterPropertyKey.DependencyProperty; public static readonly DependencyProperty OutputConnectorTemplateProperty = DependencyProperty.Register(nameof(OutputConnectorTemplate), typeof(DataTemplate), typeof(Node)); public static readonly DependencyProperty InputProperty = DependencyProperty.Register(nameof(Input), typeof(IEnumerable), typeof(Node)); diff --git a/Nodify/NodifyEditor.Dragging.cs b/Nodify/NodifyEditor.Dragging.cs new file mode 100644 index 00000000..38703a76 --- /dev/null +++ b/Nodify/NodifyEditor.Dragging.cs @@ -0,0 +1,190 @@ +using System.Windows.Input; +using System.Windows; +using System.Collections.Generic; +using System.Windows.Controls.Primitives; +using System.Diagnostics; + +namespace Nodify +{ + public partial class NodifyEditor + { + public static readonly DependencyProperty ItemsDragStartedCommandProperty = DependencyProperty.Register(nameof(ItemsDragStartedCommand), typeof(ICommand), typeof(NodifyEditor)); + public static readonly DependencyProperty ItemsDragCompletedCommandProperty = DependencyProperty.Register(nameof(ItemsDragCompletedCommand), typeof(ICommand), typeof(NodifyEditor)); + + protected static readonly DependencyPropertyKey IsDraggingPropertyKey = DependencyProperty.RegisterReadOnly(nameof(IsDragging), typeof(bool), typeof(NodifyEditor), new FrameworkPropertyMetadata(BoxValue.False, OnIsDraggingChanged)); + public static readonly DependencyProperty IsDraggingProperty = IsDraggingPropertyKey.DependencyProperty; + + private static void OnIsDraggingChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var editor = (NodifyEditor)d; + + if ((bool)e.NewValue == true) + { + editor.OnItemsDragStarted(); + } + else + { + editor.OnItemsDragCompleted(); + } + } + + private void OnItemsDragCompleted() + { + if (ItemsDragCompletedCommand?.CanExecute(DataContext) ?? false) + ItemsDragCompletedCommand.Execute(DataContext); + } + + private void OnItemsDragStarted() + { + if (ItemsDragStartedCommand?.CanExecute(DataContext) ?? false) + ItemsDragStartedCommand.Execute(DataContext); + } + + /// + /// Invoked when a drag operation starts for the , or when is set to true. + /// + public ICommand? ItemsDragStartedCommand + { + get => (ICommand?)GetValue(ItemsDragStartedCommandProperty); + set => SetValue(ItemsDragStartedCommandProperty, value); + } + + /// + /// Invoked when a drag operation is completed for the , or when is set to false. + /// + public ICommand? ItemsDragCompletedCommand + { + get => (ICommand?)GetValue(ItemsDragCompletedCommandProperty); + set => SetValue(ItemsDragCompletedCommandProperty, value); + } + + /// + /// Gets a value that indicates whether a dragging operation is in progress. + /// + public bool IsDragging + { + get => (bool)GetValue(IsDraggingProperty); + private set => SetValue(IsDraggingPropertyKey, value); + } + + /// + /// Gets or sets if the current position of containers that are being dragged should not be committed until the end of the dragging operation. + /// + public static bool EnableDraggingContainersOptimizations { get; set; } = true; + + private IDraggingStrategy? _draggingStrategy; + + private void RegisterDragEvents() + { + AddHandler(ItemContainer.DragStartedEvent, new DragStartedEventHandler(OnItemsDragStarted)); + AddHandler(ItemContainer.DragCompletedEvent, new DragCompletedEventHandler(OnItemsDragCompleted)); + AddHandler(ItemContainer.DragDeltaEvent, new DragDeltaEventHandler(OnItemsDragDelta)); + } + + /// + /// Initiates the dragging operation using the currently selected s. + /// + /// This method has no effect if a dragging operation is already in progress. + public void BeginDragging() + => BeginDragging(SelectedContainers); + + /// + /// Initiates the dragging operation for the specified s. + /// + /// The collection of item containers to be dragged. + /// This method has no effect if a dragging operation is already in progress. + public void BeginDragging(IEnumerable containers) + { + if(IsDragging) + { + return; + } + + IsDragging = true; + _draggingStrategy = CreateDraggingStrategy(containers); + } + + /// + /// Updates the position of the items being dragged by a specified offset. + /// + /// The vector by which to adjust the position of the dragged items. + /// + /// This method adjusts the items positions incrementally. It should only be called while a dragging operation is in progress (see ). + /// + public void UpdateDragging(Vector amount) + { + Debug.Assert(IsDragging); + _draggingStrategy!.Update(amount); + } + + /// + /// Completes the dragging operation, finalizing the position of the dragged items. + /// + /// This method has no effect if there's no dragging operation in progress. + public void EndDragging() + { + if (!IsDragging) + { + return; + } + + IsBulkUpdatingItems = true; + _draggingStrategy!.End(); + IsBulkUpdatingItems = false; + + // Draw the containers at the new position. + ItemsHost.InvalidateArrange(); + + _draggingStrategy = null; + IsDragging = false; + } + + /// + /// Cancels the ongoing dragging operation, reverting any changes made to the positions of the dragged items. + /// + /// This method has no effect if there's no dragging operation in progress. + public void CancelDragging() + { + if (!ItemContainer.AllowDraggingCancellation || !IsDragging) + { + return; + } + + _draggingStrategy!.Abort(); + IsDragging = false; + } + + private IDraggingStrategy CreateDraggingStrategy(IEnumerable containers) + { + if (EnableDraggingContainersOptimizations) + { + return new DraggingOptimized(containers, GridCellSize); + } + + return new DraggingSimple(containers, GridCellSize); + } + + private void OnItemsDragStarted(object sender, DragStartedEventArgs e) + { + BeginDragging(); + e.Handled = true; + } + + private void OnItemsDragDelta(object sender, DragDeltaEventArgs e) + { + UpdateDragging(new Vector(e.HorizontalChange, e.VerticalChange)); + } + + private void OnItemsDragCompleted(object sender, DragCompletedEventArgs e) + { + if (e.Canceled) + { + CancelDragging(); + } + else + { + EndDragging(); + } + } + } +} diff --git a/Nodify/NodifyEditor.PushingItems.cs b/Nodify/NodifyEditor.PushingItems.cs index f9bc85f9..3afd47a8 100644 --- a/Nodify/NodifyEditor.PushingItems.cs +++ b/Nodify/NodifyEditor.PushingItems.cs @@ -13,38 +13,12 @@ public partial class NodifyEditor protected static readonly DependencyPropertyKey PushedAreaPropertyKey = DependencyProperty.RegisterReadOnly(nameof(PushedArea), typeof(Rect), typeof(NodifyEditor), new FrameworkPropertyMetadata(BoxValue.Rect)); public static readonly DependencyProperty PushedAreaProperty = PushedAreaPropertyKey.DependencyProperty; - protected static readonly DependencyPropertyKey IsPushingItemsPropertyKey = DependencyProperty.RegisterReadOnly(nameof(IsPushingItems), typeof(bool), typeof(NodifyEditor), new FrameworkPropertyMetadata(BoxValue.False, OnIsPushingItemsChanged)); + protected static readonly DependencyPropertyKey IsPushingItemsPropertyKey = DependencyProperty.RegisterReadOnly(nameof(IsPushingItems), typeof(bool), typeof(NodifyEditor), new FrameworkPropertyMetadata(BoxValue.False)); public static readonly DependencyProperty IsPushingItemsProperty = IsPushingItemsPropertyKey.DependencyProperty; protected static readonly DependencyPropertyKey PushedAreaOrientationPropertyKey = DependencyProperty.RegisterReadOnly(nameof(PushedAreaOrientation), typeof(Orientation), typeof(NodifyEditor), new FrameworkPropertyMetadata(Orientation.Horizontal)); public static readonly DependencyProperty PushedAreaOrientationProperty = PushedAreaOrientationPropertyKey.DependencyProperty; - private static void OnIsPushingItemsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - var editor = (NodifyEditor)d; - - if ((bool)e.NewValue == true) - { - editor.OnItemsPushStarted(); - } - else - { - editor.OnItemsPushCompleted(); - } - } - - private void OnItemsPushCompleted() - { - if (ItemsDragCompletedCommand?.CanExecute(DataContext) ?? false) - ItemsDragCompletedCommand.Execute(DataContext); - } - - private void OnItemsPushStarted() - { - if (ItemsDragStartedCommand?.CanExecute(DataContext) ?? false) - ItemsDragStartedCommand.Execute(DataContext); - } - /// /// Gets the currently pushed area while is true. /// @@ -109,27 +83,12 @@ public void BeginPushingItems(Point location, Orientation orientation) PushedArea = _pushStrategy.Start(location); } - /// - /// Cancels the current pushing operation and reverts the to its initial state if is true. - /// - /// This method has no effect if there's no pushing operation in progress. - public void CancelPushingItems() - { - if (!AllowPushItemsCancellation || !IsPushingItems) - { - return; - } - - PushedArea = _pushStrategy!.Cancel(); - IsPushingItems = false; - } - /// /// Updates the pushed area based on the specified amount taking the into account. /// /// The amount to adjust the pushed area by. /// - /// This method adjusts the pushed area incrementally. It should only be called while a pushing operation is active (see ). + /// This method adjusts the pushed area incrementally. It should only be called while a pushing operation is in progress (see ). /// public void UpdatePushedArea(Vector amount) { @@ -153,11 +112,26 @@ public void EndPushingItems() IsPushingItems = false; } + /// + /// Cancels the current pushing operation and reverts the to its initial state if is true. + /// + /// This method has no effect if there's no pushing operation in progress. + public void CancelPushingItems() + { + if (!AllowPushItemsCancellation || !IsPushingItems) + { + return; + } + + PushedArea = _pushStrategy!.Cancel(); + IsPushingItems = false; + } + private void UpdatePushedArea() { if (IsPushingItems) { - PushedArea = _pushStrategy!.OnViewportChanged(); + PushedArea = _pushStrategy!.GetPushedArea(); } } diff --git a/Nodify/NodifyEditor.cs b/Nodify/NodifyEditor.cs index 6902532b..4ace8a65 100644 --- a/Nodify/NodifyEditor.cs +++ b/Nodify/NodifyEditor.cs @@ -4,7 +4,6 @@ using System.ComponentModel; using System.Windows; using System.Windows.Controls; -using System.Windows.Controls.Primitives; using System.Windows.Input; using System.Windows.Markup; using System.Windows.Media; @@ -35,7 +34,7 @@ public partial class NodifyEditor public static readonly DependencyProperty ItemsExtentProperty = DependencyProperty.Register(nameof(ItemsExtent), typeof(Rect), typeof(NodifyEditor), new FrameworkPropertyMetadata(BoxValue.Rect, OnItemsExtentChanged)); public static readonly DependencyProperty DecoratorsExtentProperty = DependencyProperty.Register(nameof(DecoratorsExtent), typeof(Rect), typeof(NodifyEditor), new FrameworkPropertyMetadata(BoxValue.Rect)); - protected internal static readonly DependencyPropertyKey ViewportTransformPropertyKey = DependencyProperty.RegisterReadOnly(nameof(ViewportTransform), typeof(Transform), typeof(NodifyEditor), new FrameworkPropertyMetadata(new TransformGroup())); + protected static readonly DependencyPropertyKey ViewportTransformPropertyKey = DependencyProperty.RegisterReadOnly(nameof(ViewportTransform), typeof(Transform), typeof(NodifyEditor), new FrameworkPropertyMetadata(new TransformGroup())); public static readonly DependencyProperty ViewportTransformProperty = ViewportTransformPropertyKey.DependencyProperty; #region Callbacks @@ -317,7 +316,7 @@ public Style DecoratorContainerStyle #region Readonly Dependency Properties - protected static readonly DependencyPropertyKey MouseLocationPropertyKey = DependencyProperty.RegisterReadOnly(nameof(MouseLocation), typeof(Point), typeof(NodifyEditor), new FrameworkPropertyMetadata(BoxValue.Point)); + private static readonly DependencyPropertyKey MouseLocationPropertyKey = DependencyProperty.RegisterReadOnly(nameof(MouseLocation), typeof(Point), typeof(NodifyEditor), new FrameworkPropertyMetadata(BoxValue.Point)); public static readonly DependencyProperty MouseLocationProperty = MouseLocationPropertyKey.DependencyProperty; /// @@ -397,8 +396,6 @@ public bool DisableZooming public static readonly DependencyProperty ConnectionStartedCommandProperty = DependencyProperty.Register(nameof(ConnectionStartedCommand), typeof(ICommand), typeof(NodifyEditor)); public static readonly DependencyProperty DisconnectConnectorCommandProperty = DependencyProperty.Register(nameof(DisconnectConnectorCommand), typeof(ICommand), typeof(NodifyEditor)); public static readonly DependencyProperty RemoveConnectionCommandProperty = DependencyProperty.Register(nameof(RemoveConnectionCommand), typeof(ICommand), typeof(NodifyEditor)); - public static readonly DependencyProperty ItemsDragStartedCommandProperty = DependencyProperty.Register(nameof(ItemsDragStartedCommand), typeof(ICommand), typeof(NodifyEditor)); - public static readonly DependencyProperty ItemsDragCompletedCommandProperty = DependencyProperty.Register(nameof(ItemsDragCompletedCommand), typeof(ICommand), typeof(NodifyEditor)); /// /// Invoked when the is completed.
@@ -444,24 +441,6 @@ public ICommand? RemoveConnectionCommand set => SetValue(RemoveConnectionCommandProperty, value); } - /// - /// Invoked when a drag operation starts for the , or when is set to true. - /// - public ICommand? ItemsDragStartedCommand - { - get => (ICommand?)GetValue(ItemsDragStartedCommandProperty); - set => SetValue(ItemsDragStartedCommandProperty, value); - } - - /// - /// Invoked when a drag operation is completed for the , or when is set to false. - /// - public ICommand? ItemsDragCompletedCommand - { - get => (ICommand?)GetValue(ItemsDragCompletedCommandProperty); - set => SetValue(ItemsDragCompletedCommandProperty, value); - } - #endregion #region Fields @@ -492,11 +471,6 @@ public ICommand? ItemsDragCompletedCommand ///
public static double FitToScreenExtentMargin { get; set; } = 30; - /// - /// Gets or sets if the current position of containers that are being dragged should not be committed until the end of the dragging operation. - /// - public static bool EnableDraggingContainersOptimizations { get; set; } = true; - /// /// Tells if the is doing operations on multiple items at once. /// @@ -512,8 +486,6 @@ public ICommand? ItemsDragCompletedCommand ///
protected internal UIElement ConnectionsHost { get; private set; } = default!; - private IDraggingStrategy? _draggingStrategy; - /// /// Gets a list of all s. /// @@ -557,9 +529,7 @@ public NodifyEditor() AddHandler(BaseConnection.DisconnectEvent, new ConnectionEventHandler(OnRemoveConnection)); - AddHandler(ItemContainer.DragStartedEvent, new DragStartedEventHandler(OnItemsDragStarted)); - AddHandler(ItemContainer.DragCompletedEvent, new DragCompletedEventHandler(OnItemsDragCompleted)); - AddHandler(ItemContainer.DragDeltaEvent, new DragDeltaEventHandler(OnItemsDragDelta)); + RegisterDragEvents(); var transform = new TransformGroup(); transform.Children.Add(ScaleTransform); @@ -870,66 +840,6 @@ protected override void OnKeyDown(KeyEventArgs e) #endregion - #region Dragging - - private void OnItemsDragDelta(object sender, DragDeltaEventArgs e) - { - _draggingStrategy?.Update(new Vector(e.HorizontalChange, e.VerticalChange)); - } - - private void OnItemsDragCompleted(object sender, DragCompletedEventArgs e) - { - if (e.Canceled && ItemContainer.AllowDraggingCancellation) - { - _draggingStrategy?.Abort(); - } - else - { - IsBulkUpdatingItems = true; - - _draggingStrategy?.End(); - - IsBulkUpdatingItems = false; - - // Draw the containers at the new position. - ItemsHost.InvalidateArrange(); - } - - if (ItemsDragCompletedCommand?.CanExecute(DataContext) ?? false) - { - ItemsDragCompletedCommand.Execute(DataContext); - } - } - - private void OnItemsDragStarted(object sender, DragStartedEventArgs e) - { - IList selectedItems = base.SelectedItems; - - _draggingStrategy = CreateDraggingStrategy(SelectedContainers); - - if (selectedItems.Count > 0) - { - if (ItemsDragStartedCommand?.CanExecute(DataContext) ?? false) - { - ItemsDragStartedCommand.Execute(DataContext); - } - - e.Handled = true; - } - } - - internal IDraggingStrategy CreateDraggingStrategy(IEnumerable containers) - { - if (EnableDraggingContainersOptimizations) - { - return new DraggingOptimized(containers, GridCellSize); - } - - return new DraggingSimple(containers, GridCellSize); - } - - #endregion - /// protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo) {