2016-05-03 14 views
6

Sto sviluppando un'applicazione touch WPF. Ho un visualizzatore di scorrimento contenente pulsanti. Voglio scorrere il display quando tocchi-trascinare i pulsanti e chiamare il comando del pulsante quando tocco. Ecco il codice per iniziare:ScrollViewer WPF: tocca = fai clic, tocca e tieni premuto/trascina = scorri. Come ottenere questo?

<Window x:Class="wpf_Button_Scroll.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:my="clr-namespace:wpf_Button_Scroll" 
    Title="MainWindow" Height="350" Width="200"> 
<Window.DataContext> 
    <my:MyViewModel /> 
</Window.DataContext> 

<Grid> 
    <ScrollViewer> 
     <ListView ItemsSource="{Binding MyData}" HorizontalAlignment="Stretch"> 
      <ListView.ItemTemplate> 
       <DataTemplate> 
        <Button Content="{Binding}" 
          Command="{Binding DataContext.MyCommand, RelativeSource={RelativeSource AncestorType=ItemsControl}}" 
          CommandParameter="{Binding}" 
          Margin="5 2" Width="150" Height="50" 
          FontSize="30" /> 
       </DataTemplate> 
      </ListView.ItemTemplate> 
     </ListView> 
    </ScrollViewer> 
</Grid> 
</Window> 

E il modello di vista:

namespace wpf_Button_Scroll 
{ 
class MyViewModel 
{ 
    public MyViewModel() 
    { 
     MyCommand = new ICommandImplementation(); 
    } 

    public string[] MyData 
    { 
     get 
     { 
      return new string[]{ 
       "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", 
       "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen", "twenty" 
      }; 
     } 
    } 

    public ICommand MyCommand { get; private set; } 

    private class ICommandImplementation : ICommand 
    { 
     public bool CanExecute(object parameter) { return true; } 
     public event EventHandler CanExecuteChanged; 
     public void Execute(object parameter) { System.Windows.MessageBox.Show("Button clicked! " + (parameter ?? "").ToString()); } 
    } 
} 
} 

comportamento previsto:

  1. quando l'utente tocca un pulsante, viene visualizzata una finestra di messaggio con il testo "Pulsante cliccato!" ==> OK

  2. quando l'utente preme un pulsante e si sposta il dito (senza rilasciare), i pulsanti di scorrere verso l'alto e verso il basso ==> NOK

Come posso ottenere lo scorrimento in uno ScrollViewer che contiene pulsanti?

Sto sviluppando su Visual Studio 2013 su Windows 7 e sto prendendo di mira un desktop Windows 7 e un tablet Windows 8 con la stessa base di codice. Framework 4.0. Se è veramente necessario, posso effettuare l'aggiornamento a 4.5.2 (abbiamo molti utenti, quindi non è banale da aggiornare).

+0

Il problema è stato risolto? (In realtà mi aspettavo che funzionasse automaticamente) –

+0

@ H.B. sì, il mio problema è risolto.Vedi la risposta accettata (che ho appena modificato perché non era molto chiara). – DonkeyMaster

+0

Possibile duplicato di [WPF Scrollviewer su tablet touch screen] (http://stackoverflow.com/questions/17294135/wpf-scrollviewer-on-touch-screen-tablet) – DonkeyMaster

risposta

0

Bene, questo è così semplice che mi sento in imbarazzo che non l'ho trovato prima. Ho dovuto impostare la proprietà PanningMode su ScrollViewer.

Ti piace questa:

<ScrollViewer PanningMode="VerticalOnly"> 

codice finale:

<Window x:Class="wpf_Button_Scroll.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:my="clr-namespace:wpf_Button_Scroll" 
    Title="MainWindow" Height="350" Width="200"> 
<Window.DataContext> 
    <my:MyViewModel /> 
</Window.DataContext> 

<Grid> 
    <ScrollViewer PanningMode="VerticalOnly"> 
     <ListView ItemsSource="{Binding MyData}" HorizontalAlignment="Stretch"> 
      <ListView.ItemTemplate> 
       <DataTemplate> 
        <Button Content="{Binding}" 
          Command="{Binding DataContext.MyCommand, RelativeSource={RelativeSource AncestorType=ItemsControl}}" 
          CommandParameter="{Binding}" 
          Margin="5 2" Width="150" Height="50" 
          FontSize="30" /> 
       </DataTemplate> 
      </ListView.ItemTemplate> 
     </ListView> 
    </ScrollViewer> 
</Grid> 
</Window> 

la vista del modello non cambia

+0

dove hai inserito questo attributo esattamente? –

+0

@KyloRen Ho chiarito la mia risposta – DonkeyMaster

+0

ok .. ma sono ancora bloccato con la parte di scorrimento nell'app WPF win ... PanningMode = "VerticalOnly" non sembra funzionare nel trascinamento .. –

1

Dato che c'erano Button(s) nel ListView per la quale dobbiamo fare il command ottenere eseguito quando previsto. Quindi questa è stata la parte difficile. L'ho fatto in modo di seguito:

XAML:

<Window.DataContext> 
    <local:MyViewModel /> 
</Window.DataContext> 

<Grid> 
    <ScrollViewer> 
     <ListView ItemsSource="{Binding MyData}" HorizontalAlignment="Stretch" Name="listview" ScrollViewer.PanningMode="VerticalOnly"> 
      <ListView.ItemTemplate> 
       <DataTemplate> 
        <Button Content="{Binding}" 
         Command="{Binding DataContext.MyCommand, RelativeSource={RelativeSource AncestorType=ItemsControl}}" 
         CommandParameter="{Binding}" 
         Margin="5 2" Width="150" Height="50" 
         FontSize="30" /> 
       </DataTemplate> 
      </ListView.ItemTemplate> 
      <ListView.Resources> 
       <Style TargetType="Button"> 
        <EventSetter Event="PreviewMouseMove" Handler="PreviewMouseMove" />       
        <EventSetter Event="Drop" Handler="Drop" />      
        <Setter Property="AllowDrop" Value="True" />       
       </Style> 
      </ListView.Resources> 
     </ListView> 
    </ScrollViewer> 
</Grid> 

ViewModel:

class MyViewModel 
{ 
    public MyViewModel() 
    { 
     MyCommand = new ICommandImplementation(); 
    } 

    public ObservableCollection<string> MyData 
    { 
     get 
     { 
      return new ObservableCollection<string>(new string[]{ 
      "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", 
      "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen", "twenty" 
      }); 
     } 
    } 

    public ICommand MyCommand { get; private set; } 

    private class ICommandImplementation : ICommand 
    { 
     public bool CanExecute(object parameter) { return true; } 
     public event EventHandler CanExecuteChanged; 
     public void Execute(object parameter) { System.Windows.MessageBox.Show("Button clicked! " + (parameter ?? "").ToString()); } 
    } 
} 

Eventi:

private void Drop(object sender, DragEventArgs e) 
    { 
     var source = e.Data.GetData("Source") as string; 
     if (source != null) 
     { 
      int newIndex = listview.Items.IndexOf((sender as Button).Content); 
      var list = listview.ItemsSource as ObservableCollection<string>; 
      list.RemoveAt(list.IndexOf(source)); 
      list.Insert(newIndex, source); 
     } 
    } 

    private void PreviewMouseMove(object sender, MouseEventArgs e) 
    { 
     if (e.LeftButton == MouseButtonState.Pressed) 
     { 
      Task.Factory.StartNew(new Action(() => 
       { 
        Thread.Sleep(500); 
        App.Current.Dispatcher.BeginInvoke(new Action(() => 
         { 
          if (e.LeftButton == MouseButtonState.Pressed) 
          {          
           var data = new DataObject(); 
           data.SetData("Source", (sender as Button).Content); 
           DragDrop.DoDragDrop(sender as DependencyObject, data, DragDropEffects.Move); 
           e.Handled = true; 
          } 
         }), null); 
       }), CancellationToken.None); 
     }   
    } 

In this link Ho scritto come funziona Drag & Drop in relazione agli eventi e alla loro condivisione dei dati.

E sto ancora lavorando alla parte di scorrimento.

+1

Questa è metà della risposta a una domanda che non ho posto. https://stackoverflow.com/questions/37008970/wpf-scrollviewer-tap-click-tap-and-hold-drag-scroll-how-to-achieve-this#comment62029981_37122176 – DonkeyMaster

+0

@DonkeyMaster ... penso non per il tablet ma per il trascinamento del mouse quel link sarà utile ... So che è fuori tema, ma per un'istanza ho davvero dimenticato la domanda dopo questi molti giorni e ho solo ricordato la parte del problema di scorrimento ... grazie per averlo indicato:) –

Problemi correlati