Gong-wpf-dragdrop: Arrastar e soltar ListBox - tela sensível ao toque

Criado em 1 out. 2014  ·  19Comentários  ·  Fonte: punker76/gong-wpf-dragdrop

Não consigo usar a funcionalidade de arrastar e soltar em telas sensíveis ao toque com ListBox / ListView.

Está planejado para o futuro ou alguém tem uma solução alternativa para isso?

Feature Request

Comentários muito úteis

Adicionar ScrollViewer.PanningMode="None" a ListBox corrigiu o problema. Passei metade do dia trabalhando nisso e você acabou de me salvar a outra metade! Muito obrigado !!!

Todos 19 comentários

@psoma eu faria isso, mas não posso testar no mundo real, porque não tenho nenhum dispositivo tocável :-(

Há também a questão de como se deseja iniciar a operação de arrasto,
algumas coisas fazem sentido para começar a arrastar no toque para baixo, outras provavelmente querem
um toque longo.
Em 1º de outubro de 2014, 11h28, "Jan Karger" [email protected] escreveu:

@psoma https://github.com/psoma eu faria isso, mas não posso testar isso
no mundo real, porque eu não tenho nenhum dispositivo tocável :-(

-
Responda a este e-mail diretamente ou visualize-o no GitHub
https://github.com/punker76/gong-wpf-dragdrop/issues/110#issuecomment -57512449
.

Que tipo de tela sensível ao toque você está usando? Estou usando esta biblioteca com tela de toque resistiva e não tenho problemas.

É criado usando DoDragDrop ().

A tela sensível ao toque estava em nossa máquina de teste, acho que um tablet Lenovo Yoga 2.

Tendo o mesmo problema em todas as telas de toque. Testando com Surface Pro 2, 3 e 4.

Eu tive um problema semelhante e no final decidi que era um conflito entre a rolagem inercial nativa na caixa de listagem e os controles derivados. Faz sentido porque é muito difícil dizer a diferença entre "pressione e mova, o que significa rolar a janela" e "pressione e mova. O que significa pegar aquele item para arrastar"

Você pode tentar desativar o PanningMode, isso pode ajudar?

Adicionar ScrollViewer.PanningMode="None" a ListBox corrigiu o problema. Passei metade do dia trabalhando nisso e você acabou de me salvar a outra metade! Muito obrigado !!!

Sem problemas, fico feliz por ter ajudado: D

O problema é que configurar o PanningMode mal é uma solução alternativa, e ter um aplicativo habilitado para toque onde você não pode rolar uma lista com o toque é impossível. Qualquer atualização sobre isso? @ punker76
Algo baseado em um gesto de espera para acionar o arrasto seria ótimo, mas ainda não descobri como implementá-lo

Não sei se isso ajuda, ou se há falhas óbvias nisso que eu ainda não percebi, mas uma solução que _parece_ estar funcionando para mim é:

  • Deixe PanningMode definido com seu valor padrão ( Both , eu acredito?)
  • No evento SelectionChanged , altere PanningMode para None
  • Defina um cronômetro que dispara após um breve intervalo (800 milissegundos parece razoável para meu aplicativo específico)
  • Quando o cronômetro disparar, desligue-o novamente e redefina PanningMode para Both

Código pseudo-y:

  ctor()
  {
    // There are of course a bunch of different timers. When coding this, I got my
    // grubby fingers onto System.Timers.Timer first, so that's what I used here :-P
    _touchDragTimer = new Timer();
    _touchDragTimer.Interval = 800;
    _touchDragTimer.Elapsed += _touchDragTimer_Elapsed;
  }

  void lstItems_SelectionChanged(sender, e)
  {
    _touchDragTimer.Stop();
    lstItems.SetValue(ScrollViewer.PanningMode, PanningMode.None);
    _touchDragTimer.Start();
  }

  void _touchDragTimer_Elapsed(sender, e)
  {
    _touchDragTimer.Stop();

    Dispatcher.Invoke(
      () =>
      {
        lstItems.SetValue(ScrollViewer.PanningMode, PanningMode.Both);
      });
  }

Com este código, você pode arrastar a visualização o quanto quiser, mas se quiser arrastar um item, toque nele uma vez para selecioná-lo e, em seguida, terá um breve intervalo para iniciar a operação de arrastar. Deixe-o sentar e ele reverte para o comportamento de scrolly.

Eu não investiguei se isso seria fácil de integrar diretamente no GongSolutions.Wpf.DragDrop, mas talvez alguém possa achar útil (ou ser capaz de me dizer por que eu não deveria fazer isso! :-D).

Tocar, soltar, segurar e arrastar é um gesto bastante comum para indicar que você deseja arrastar em vez de rolar.

Também estou interessado neste recurso, seria ótimo tê-lo!

Não sei se isso ajuda, ou se há falhas óbvias nisso que eu ainda não percebi, mas uma solução que _parece_ estar funcionando para mim é:

  • Deixe PanningMode definido com seu valor padrão ( Both , eu acredito?)
  • No evento SelectionChanged , altere PanningMode para None
  • Defina um cronômetro que dispara após um breve intervalo (800 milissegundos parece razoável para meu aplicativo específico)
  • Quando o cronômetro disparar, desligue-o novamente e redefina PanningMode para Both

Código pseudo-y:

  ctor()
  {
    // There are of course a bunch of different timers. When coding this, I got my
    // grubby fingers onto System.Timers.Timer first, so that's what I used here :-P
    _touchDragTimer = new Timer();
    _touchDragTimer.Interval = 800;
    _touchDragTimer.Elapsed += _touchDragTimer_Elapsed;
  }

  void lstItems_SelectionChanged(sender, e)
  {
    _touchDragTimer.Stop();
    lstItems.SetValue(ScrollViewer.PanningMode, PanningMode.None);
    _touchDragTimer.Start();
  }

  void _touchDragTimer_Elapsed(sender, e)
  {
    _touchDragTimer.Stop();

    Dispatcher.Invoke(
      () =>
      {
        lstItems.SetValue(ScrollViewer.PanningMode, PanningMode.Both);
      });
  }

Com este código, você pode arrastar a visualização o quanto quiser, mas se quiser arrastar um item, toque nele uma vez para selecioná-lo e, em seguida, terá um breve intervalo para iniciar a operação de arrastar. Deixe-o sentar e ele reverte para o comportamento de scrolly.

Eu não investiguei se isso seria fácil de integrar diretamente no GongSolutions.Wpf.DragDrop, mas talvez alguém possa achar útil (ou ser capaz de me dizer por que eu não deveria fazer isso! :-D).

Eu tentei isso, mas esta parte lstItems.SetValue(ScrollViewer.PanningMode, PanningMode.Both); gera um erro para mim

Uma referência de objeto é necessária para o campo não estático 'ScrollViewer.PanningMode'

Eu tentei isso, mas esta parte lstItems.SetValue(ScrollViewer.PanningMode, PanningMode.Both); gera um erro para mim

Uma referência de objeto é necessária para o campo não estático 'ScrollViewer.PanningMode'

Use ScrollViewer.PanningModeProperty vez disso.

Opa, sim, desculpe por isso, foi um erro de digitação. 😳

Mudei um pouco o código. Em vez de alterar o PanningMode no evento SelectionChanged, eu o tenho no PreviewTouchDown, dessa forma, o arrasto é instantâneo, em vez de ter que selecionar o item e, em seguida, arrastá-lo.

private void list_PreviewTouchDown(object sender, System.Windows.Input.TouchEventArgs e)
{
            _touchDragTimer.Stop();
            lst_scheduled.SetValue(ScrollViewer.PanningModeProperty, PanningMode.None);
            _touchDragTimer.Start();
}

Mudei um pouco o código. Em vez de alterar o PanningMode no evento SelectionChanged, eu o tenho no PreviewTouchDown, dessa forma, o arrasto é instantâneo, em vez de ter que selecionar o item e, em seguida, arrastá-lo.

Mas então você não está mais fazendo o gesto de tocar duas vezes e arrastar, está?

Na verdade, como você rola o contêiner do item? Com essa mudança, por que ter modos de panorâmica diferentes? Você poderia apenas deixá-lo permanentemente definido como None , não é?

Na verdade, como você rola o contêiner do item? Com essa mudança, por que ter modos de panorâmica diferentes? Você poderia apenas deixá-lo permanentemente definido como None , não é?

Sim você está certo. Quando testei inicialmente, havia apenas alguns itens na caixa :( Eu só quero arrastar suavemente, sem tocar duas vezes. Talvez segure e arraste bastasse.

Esta página foi útil?
0 / 5 - 0 avaliações