长按GridView控件(XAML)后启用拖放和重新排序

时间:2015-06-15 13:38:25

标签: c# xaml windows-store-apps

我使用XAML中Windows 8.1 Windows应用商店应用模板中的Items Page模板。该页面具有一个包含多个项元素的大型GridView控件。

我想启用项目的拖动和重新排序,但只有在用户长时间点击其中一项后(类似于在Windows Tablet开始菜单和iOS / Android主屏幕上完成的操作)

我已尝试绑定Holding事件并启用CanDragItemsCanReorderItems,但用户无法在Holding事件期间开始拖动该项。< / p>

这是GridView定义:

<GridView
        x:Name="itemGridView"
        AutomationProperties.AutomationId="ItemsGridView"
        AutomationProperties.Name="Items"
        TabIndex="1"
        Grid.RowSpan="2"
        Padding="116,136,116,46"
        ItemsSource="{Binding Source={StaticResource itemsViewSource}}"
        SelectionMode="None"
        IsSwipeEnabled="False"
        IsItemClickEnabled="True"
        CanReorderItems="False"
        AllowDrop="False"
        CanDragItems="False" 
        ItemClick="itemGridView_ItemClick"
        >

在后面的代码中有这个:

void OnHolding(object sender, HoldingRoutedEventArgs e)
    {
        if( e.HoldingState == Windows.UI.Input.HoldingState.Started)
        {
            Debug.WriteLine("Drag Start");
            itemGridView.CanDragItems = true;
            itemGridView.IsSwipeEnabled = true;
            itemGridView.CanReorderItems = true;
            itemGridView.AllowDrop = true;
        }
        else
        {
            Debug.WriteLine("Drag End");
            itemGridView.CanDragItems = false;
            itemGridView.IsSwipeEnabled = false;
            itemGridView.CanReorderItems = false;
            itemGridView.AllowDrop = false;
        }
    }

谢谢!

2 个答案:

答案 0 :(得分:1)

经过大惊小怪和追逐事件后,我能够在笔,鼠标和触控设备上获得预期的效果。

以下代码不能保证是完成长按拖动的最佳方法,但它在我的Windows 8.1设备上运行。我鼓励有人找到更好的解决方案,因为这个问题很麻烦。

背后的代码如下:

    private bool isHolding = false;
    private bool canUserDragItem = false;

    // If a user moves their pointer outside the item's area or releases their pointer, stop all holding/dragging actions.
    private void Grid_StopAllowDrag(object sender, PointerRoutedEventArgs e)
    {
        canUserDragItem = false;
        isHolding = false;
    }

    // If a user starts dragging an item, check and see if they are holding the item first.
    private void itemGridView_DragItemsStarting(object sender, DragItemsStartingEventArgs e)
    {
        if (!canUserDragItem) e.Cancel = true;
    }

    private async void Grid_PointerPressed(object sender, PointerRoutedEventArgs e)
    {
        // Whenever a user presses the pointer inside the item, wait for half a second, then decide if the user is holding the item.
        isHolding = true;

        await Task.Delay(500); // Wait for some amount of time before allowing them to drag

        if (isHolding) // If the user is still holding, allow them to drag the item.
        { 
            canUserDragItem = true; // Allow them to drag now
            // TODO: Make it apparent that the user is able to drag the item now.
        }
    }

XAML看起来像这样:

<GridView
            x:Name="itemGridView"
            AutomationProperties.AutomationId="ItemsGridView"
            AutomationProperties.Name="Items"
            TabIndex="1"
            Grid.RowSpan="2"
            Padding="116,136,116,46"
            ItemsSource="{Binding Source={StaticResource itemsViewSource}}"
            SelectionMode="None"
            IsSwipeEnabled="True" <!-- Enable dragging on touch devices -->
            CanReorderItems="True" <!-- Allow users to try to start dragging -->
            AllowDrop="True"
            CanDragItems="True"
            DragItemsStarting="itemGridView_DragItemsStarting" <!-- Stop dragging while not holding -->
            >
            <GridView.ItemTemplate>
                <DataTemplate>
                    <Grid HorizontalAlignment="Left" Width="250" Height="250"
                          <!-- Items must be given these event handlers -->
                          PointerPressed="Grid_PointerPressed"
                          PointerReleased="Grid_StopAllowDrag"
                          PointerCanceled="Grid_StopAllowDrag"
                          PointerCaptureLost="Grid_StopAllowDrag"
                          PointerExited="Grid_StopAllowDrag"
                          >

答案 1 :(得分:0)

你需要另外一个案例。你的逻辑看起来像这样。

如果他们开始做某事。将属性设置为true。 虽然他们仍然持有属性将被设置为false。

您可能需要两个单独的活动。控股开始,持有停止。不只是那里的毯子。