2015-06-15 52 views
1

我使用XAML中Windows 8.1 Windows Store應用程序模板中的項目頁面模板。該頁面具有包含多個項目元素的大型GridView控件。在長按GridView控件(XAML)後啓用拖放和重新排序

我想啓用項目的拖拽和重新排序,但只有在用戶長時間點擊其中一個項目(類似於Windows平板電腦開始菜單和iOS/Android主屏幕上的操作方式)。

我試過綁定到Holding事件並啓用CanDragItemsCanReorderItems,但用戶無法在Holding事件期間開始拖動該項目。

這裏的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; 
     } 
    } 

謝謝!

回答

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" 
          > 
0

您需要另一個案例。你的邏輯看起來像這樣。

如果他們開始做某事。將屬性設置爲true。 雖然他們仍然持有屬性將被設置爲false。

您可能需要兩個單獨的事件。開始控股並且控股已停止。那裏不只是一條毯子。

+0

基於從調試信息的輸出,該事件似乎在充當我本來打算。當用戶長時間點擊並拖動停止點擊時,會打印拖動開始。當打印「拖動開始」時,恰好當我希望它們能夠重新排序時,但控制器不允許在沒有其他拖動的情況下重新排序。我不認爲這是問題。 – Gbps

+0

我認爲這是因爲您在啓用權限之前執行了保持事件,所以現在它沒有抓取該對象。我試圖通過這個想法,但不是你總是可以拖動項目啓用是真實的。 如果您始終將其設置爲True並刪除下面的行,它會正常工作嗎? itemGridView.CanDragItems = false; – DoomVroom