2016-05-03 11 views
6

Zajmuję się aplikacją dotykową WPF. Mam przeglądarkę zawierającą przyciski. Chcę przewinąć ekran po dotknięciu, przeciągnięciu przycisków i wywołaniu polecenia przycisku po dotknięciu. Oto niektóre kodu, aby zacząć:Przeglądarka stron WPF: dotknij = kliknij, dotknij i przytrzymaj/przeciągnij = przewiń. Jak to osiągnąć?

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

A model widok:

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()); } 
    } 
} 
} 

Przeznaczone zachowanie :

  1. gdy użytkownik kliknie przycisk, pojawi się okno komunikatu z tekstem "Przycisk kliknięty!" ==> OK

  2. gdy użytkownik naciśnie przycisk i przesuwa palcem (bez zwalniania), przyciski przewijania w górę iw dół ==> NOK

Jak mogę osiągnąć przewijania w ScrollViewer że zawiera przyciski?

Zajmuję się programowaniem Visual Studio 2013 na Windows 7 i kierujemy na pulpit Windows 7 i tablet Windows 8 z tym samym kodem. Framework 4.0. Jeśli jest to konieczne, to mogę zaktualizować do wersji 4.5.2 (mamy wielu użytkowników, więc aktualizacja nie jest banalna).

+0

Czy problem został rozwiązany? (Właściwie to oczekiwałem, że to działa domyślnie) –

+0

@ H.B. tak, mój problem został rozwiązany.Zobacz zaakceptowaną odpowiedź (którą właśnie edytowałem, ponieważ nie było to zbyt jasne). – DonkeyMaster

+0

Możliwy duplikat [Przeglądarki WPF na tablecie z ekranem dotykowym] (http://stackoverflow.com/questions/17294135/wpf-scrollviewer-on-touch-screen-tablet) – DonkeyMaster

Odpowiedz

0

Cóż, to jest tak proste, że czuję się zawstydzony, że nie znalazłem go wcześniej. Musiałem ustawić właściwość PanningMode w ScrollViewer.

Jak to:

<ScrollViewer PanningMode="VerticalOnly"> 

kod końcowa:

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

widoku modelu nie zmienia

+0

gdzie dokładnie umieściłeś ten atrybut? –

+0

@KyloRen Wyjaśniłem moją odpowiedź – DonkeyMaster

+0

ok .. ale nadal tkwię z przewijaniem części w aplikacji wygrywającej WPF ... PanningMode = "VerticalOnly" nie wydaje się działać w przeciągnięciu .. –

1

Ponieważ w ListView dla którego musimy dokonać command były Button(s) zostać wykonanym, gdy jest przeznaczony. To była najtrudniejsza część. Zrobiłem to w poniżej sposób:

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()); } 
    } 
} 

zdarzeń:

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 Napisałem, jak działa Drag & Drop w odniesieniu do wydarzeń i ich udostępniania danych.

Nadal pracuję nad przewijaniem części.

+1

To jest połowa odpowiedzi na pytanie, którego nie zadałem. https://stackoverflow.com/questions/37008970/wpf-scrollviewer-tap-click-tap-andhold-drag-scroll-how-to-achieve-this#comment62029981_37122176 – DonkeyMaster

+0

@DonkeyMaster ... myślę, że nie dla tablet, ale dla przeciągania myszą ten link będzie pomocny ... Wiem, że to nie dotyczy tematu, ale dla przykładu naprawdę zapomniałem o tym po tych wielu dniach i pamiętałem tylko przewijanie części problemu ... dziękuję za wskazanie tego:) –

Powiązane problemy