在 uwp 中拖放?

Drag and Drop in uwp?

我在堆栈面板上实现了拖放以重新排序堆栈面板的子项,但我希望堆栈面板的子项在拖动时不要超出堆栈的一侧 space,我该如何实现?

Drag and Drop in uwp?

看起来和你之前的问题一样post,我回答的是用listview替换的答案。我将向您展示另一个使用 Manipulation api 接近的工具。请参考以下代码。

<StackPanel
    x:Name="EntranceStackPanel"
    VerticalAlignment="Bottom"
    AllowDrop="True"
    Background="Black"
    Orientation="Horizontal">
    <StackPanel.ChildrenTransitions>
        <TransitionCollection>
            <EntranceThemeTransition IsStaggeringEnabled="True" />
        </TransitionCollection>
    </StackPanel.ChildrenTransitions>
    <Rectangle
        x:Name="manipulateMe"
        Width="50"
        Height="50"
        Margin="5"
        Fill="Gray" />
    <Ellipse
        Width="50"
        Height="50"
        Margin="5"
        CanDrag="True"
        Fill="Green" />
    <Rectangle
        Width="50"
        Height="50"
        Margin="5"
        CanDrag="True"
        Fill="Red" />
    <Rectangle
        Width="50"
        Height="50"
        Margin="5"
        CanDrag="True"
        Fill="Pink" />
    <Rectangle
        Width="50"
        Height="50"
        Margin="5"
        CanDrag="True"
        Fill="Purple" />
</StackPanel>

代码隐藏

private TransformGroup transforms;
 private MatrixTransform previousTransform;
 private CompositeTransform deltaTransform;
 public BlankPage1()
 {
     this.InitializeComponent();
     InitManipulationTransforms();

     manipulateMe.ManipulationStarted += new ManipulationStartedEventHandler(ManipulateMe_ManipulationStarted);
     manipulateMe.ManipulationDelta += new ManipulationDeltaEventHandler(ManipulateMe_ManipulationDelta);
     manipulateMe.ManipulationCompleted += new ManipulationCompletedEventHandler(ManipulateMe_ManipulationCompleted);
     manipulateMe.ManipulationInertiaStarting += new ManipulationInertiaStartingEventHandler(ManipulateMe_ManipulationInertiaStarting);
     manipulateMe.ManipulationMode = ManipulationModes.TranslateX;
 }

 private void ManipulateMe_ManipulationInertiaStarting(object sender, ManipulationInertiaStartingRoutedEventArgs e)
 {
   
 }

 private void ManipulateMe_ManipulationCompleted(object sender, ManipulationCompletedRoutedEventArgs e)
 {
     var ttv = manipulateMe.TransformToVisual(EntranceStackPanel);
     Point manipulateMePosition = ttv.TransformPoint(new Point(0, 0));

     EntranceStackPanel.Children.Remove(manipulateMe);

     var list = new List<double>();
     list.Add(manipulateMePosition.X);
     foreach (var item in EntranceStackPanel.Children)
     {
         list.Add(item.ActualOffset.X);               
     }
     list.Sort();
     var index = list.IndexOf(manipulateMePosition.X);     
     EntranceStackPanel.Children.Insert(index, manipulateMe);
     deltaTransform.TranslateX = - transforms.Value.OffsetX;
 }

 private void ManipulateMe_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
 {

     Canvas.SetZIndex(manipulateMe, 1);

     previousTransform.Matrix = transforms.Value;

     // Get center point for rotation
     Point center = previousTransform.TransformPoint(new Point(e.Position.X, e.Position.Y));

    deltaTransform.CenterX = center.X;
    deltaTransform.CenterY = center.Y;

     // Look at the Delta property of the ManipulationDeltaRoutedEventArgs to retrieve
     // the rotation, scale, X, and Y changes
     deltaTransform.Rotation = e.Delta.Rotation;
     deltaTransform.TranslateX = e.Delta.Translation.X;
     deltaTransform.TranslateY = e.Delta.Translation.Y;
 
     System.Diagnostics.Debug.WriteLine(deltaTransform.CenterX);
 }

 private void InitManipulationTransforms()
 {
     transforms = new TransformGroup();

     previousTransform = new MatrixTransform() { Matrix = Matrix.Identity };
     deltaTransform = new CompositeTransform();

     transforms.Children.Add(previousTransform);
     transforms.Children.Add(deltaTransform);

     // Set the render transform on the rect
     manipulateMe.RenderTransform = transforms;
 }