2010-09-16 4 views
9

Я не могу определить, как прокручивать по горизонтали с помощью колеса мыши. Вертикальная прокрутка работает хорошо, но мне нужно прокручивать содержимое по горизонтали. Мой код выглядит следующим образом:Как включить горизонтальную прокрутку с помощью мыши?

<ListBox x:Name="receiptList" 
     Margin="5,0" 
     Grid.Row="1" 
     ItemTemplate="{StaticResource receiptListItemDataTemplate}" 
     ItemsSource="{Binding OpenReceipts}" 
     ScrollViewer.VerticalScrollBarVisibility="Disabled"> 
    <ItemsControl.ItemsPanel> 
     <ItemsPanelTemplate> 
      <StackPanel Orientation="Horizontal" 
         ScrollViewer.HorizontalScrollBarVisibility="Visible"/> 
     </ItemsPanelTemplate> 
    </ItemsControl.ItemsPanel> 
</ListBox> 

Мой шаблон элемента выглядит следующим образом:

<DataTemplate x:Key="receiptListItemDataTemplate"> 
    <RadioButton GroupName="Numbers" 
       Command="{Binding Path=DataContext.SelectReceiptCommand,RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type POS:PointOfSaleControl}}}" 
       CommandParameter="{Binding }" 
       Margin="2,0" 
       IsChecked="{Binding IsSelected}"> 
     <RadioButton.Template> 
      <ControlTemplate TargetType="{x:Type RadioButton}" > 
       <Grid x:Name="receiptGrid" > 
        <Grid> 
         <Border BorderThickness="2" 
           BorderBrush="Green" 
           Height="20" 
           Width="20"> 
          <Grid x:Name="radioButtonGrid" 
            Background="DarkOrange"> 
           <TextBlock x:Name="receiptLabel" 
              HorizontalAlignment="Center" 
              VerticalAlignment="Center" 
              Text="{Binding Path=NumberInQueue, Mode=OneWay}" 
              FontWeight="Bold" 
              FontSize="12" 
              Foreground="White"> 
           </TextBlock> 
          </Grid> 
         </Border> 
        </Grid> 
       </Grid> 

       <ControlTemplate.Triggers> 
        <Trigger Property="IsChecked" Value="True"> 
         <Setter Property="Margin" 
           TargetName="receiptGrid" 
           Value="2,2,-1,-1"/> 
         <Setter Property="Background" 
           TargetName="radioButtonGrid" 
           Value="Maroon"/> 
        </Trigger> 
       </ControlTemplate.Triggers> 
      </ControlTemplate> 
     </RadioButton.Template> 
    </RadioButton>   
</DataTemplate> 

Есть еще один метод или элемент управления, который нужно добавить, чтобы получить эту функцию?

+0

Вы должны дать понять (переформулируя) в своем вопросе, что вам нужно решение для * колеса мыши * для работы. Некоторые, как я, не понимают это легко. – SandRock

ответ

5

Полное описание. Добавьте нижеприведенный класс в свой код, затем в вашем XAML установите прикрепленное свойство true на любом UIElement, которое содержит ScrollViewer в качестве визуального ребенка.

<MyVisual ScrollViewerHelper.ShiftWheelScrollsHorizontally="True" /> 

Класс:

public static class ScrollViewerHelper 
{ 
    public static readonly DependencyProperty ShiftWheelScrollsHorizontallyProperty 
     = DependencyProperty.RegisterAttached("ShiftWheelScrollsHorizontally", 
      typeof(bool), 
      typeof(ScrollViewerHelper), 
      new PropertyMetadata(false, UseHorizontalScrollingChangedCallback)); 

    private static void UseHorizontalScrollingChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     var element = d as UIElement; 

     if (element == null) 
      throw new Exception("Attached property must be used with UIElement."); 

     if ((bool)e.NewValue) 
      element.PreviewMouseWheel += OnPreviewMouseWheel; 
     else 
      element.PreviewMouseWheel -= OnPreviewMouseWheel; 
    } 

    private static void OnPreviewMouseWheel(object sender, MouseWheelEventArgs args) 
    { 
     var scrollViewer = ((UIElement)sender).FindDescendant<ScrollViewer>(); 

     if (scrollViewer == null) 
      return; 

     if (Keyboard.Modifiers != ModifierKeys.Shift) 
      return; 

     if (args.Delta < 0) 
      scrollViewer.LineRight(); 
     else 
      scrollViewer.LineLeft(); 

     args.Handled = true; 
    } 

    public static void SetShiftWheelScrollsHorizontally(ItemsControl element, bool value) => element.SetValue(ShiftWheelScrollsHorizontallyProperty, value); 
    public static bool GetShiftWheelScrollsHorizontally(ItemsControl element) => (bool)element.GetValue(ShiftWheelScrollsHorizontallyProperty); 

    [CanBeNull] 
    private static T FindDescendant<T>([CanBeNull] this DependencyObject d) where T : DependencyObject 
    { 
     if (d == null) 
      return null; 

     var childCount = VisualTreeHelper.GetChildrenCount(d); 

     for (var i = 0; i < childCount; i++) 
     { 
      var child = VisualTreeHelper.GetChild(d, i); 

      var result = child as T ?? FindDescendant<T>(child); 

      if (result != null) 
       return result; 
     } 

     return null; 
    } 
} 

Этот ответ исправляет несколько ошибок в Johannes' answer, например, не фильтруется с помощью клавиши Shift, прокрутки по горизонтали и по вертикали, в то же время (движение было по диагонали) и неспособность отключить поведение, установив свойство в false.

+0

Не компилируется. Класс и его свойство не могут быть найдены, это три ошибки в файле XAML. Файл C# не имеет собственных ошибок. VS2015 – ygoe

+0

@ygoe, вам нужно настроить xmlns, который сопоставляется с пространством имен CLR класса. –

+0

Я поместил класс в свое собственное пространство имен и уже использовал другие классы. Это не проблема. – ygoe

0

Попробуйте это:

<ListBox x:Name="receiptList" 
         Margin="5,0" 
         Grid.Row="1" 
         ItemTemplate="{StaticResource receiptListItemDataTemplate}" 
         ItemsSource="{Binding OpenReceipts}" 
         ScrollViewer.VerticalScrollBarVisibility="Disabled" 
         ScrollViewer.HorizontalScrollBarVisibility="Visible" 
          > 
       <ItemsControl.ItemsPanel> 
        <ItemsPanelTemplate> 
        <StackPanel Orientation="Horizontal" /> 
        </ItemsPanelTemplate> 
       </ItemsControl.ItemsPanel> 
</ListBox> 

UPDATE Упс, пропустил часть о колесика мыши! Извините,

Чтобы заставить колесико мыши работать, вам придется подписаться на событие колеса мыши, а мануала переместить полосу прокрутки ... Это может быть инкапсулировано поведением, но я думаю, что это единственный способ заставить его работать !

+0

Это не работает. он работает только с keyborad "->" и "<-". Прокрутка колес Moruse не работает. – Vytas999

6

Самый простой способ добавить PreviewMouseWheel слушателя к ScrollViewer, проверьте сдвига (или что вы хотите сделать, чтобы указать горизонтальной прокрутки), а затем вызвать LineLeft или LineRight (или PageLeft/PageRight) в зависимости от значения из Delta значение MouseWheelEventArgs

+0

Я не понимаю этот ответ: Как добавить PreviewMouseWheel, если ScrollViewer вообще отсутствует? – springy76

+0

Я считаю, что в шаблоне управления listbox внутри него есть scrollviewer. поэтому причина в том, что работающие свойства, такие как 'ScrollViewer.VerticalScrollBarVisibility =" Disabled ", работают. –

+0

Да, но это прикрепленные свойства. Но как мне подключить PreviewMouseWheel ScrollViewer без перезаписи шаблона управления (чего я не буду делать, потому что это нарушит автоматическую зависящую от операционной системы)? – springy76

3
(sender as ScrollViewer).ScrollToHorizontalOffset((sender as ScrollViewer).ContentHorizontalOffset + e.Delta); 
+0

Я использовал это, но должен был вычесть значение дельты, чтобы получить ожидаемое поведение (т.содержимое прокручивается вправо, когда колесико мыши вниз/к пользователю). –

+0

да спасибо, увеличение на один плз. –

8

Я написал Attached Property для этой цели использовать его на каждом ItemsControl, содержащей ScrollViewer. FindChildByType - расширение Telerik, но также можно найти here.

public static readonly DependencyProperty UseHorizontalScrollingProperty = DependencyProperty.RegisterAttached(
      "UseHorizontalScrolling", typeof(bool), typeof(ScrollViewerHelper), new PropertyMetadata(default(bool), UseHorizontalScrollingChangedCallback)); 

     private static void UseHorizontalScrollingChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs) 
     { 
      ItemsControl itemsControl = dependencyObject as ItemsControl; 

      if (itemsControl == null) throw new ArgumentException("Element is not an ItemsControl"); 

      itemsControl.PreviewMouseWheel += delegate(object sender, MouseWheelEventArgs args) 
      { 
       ScrollViewer scrollViewer = itemsControl.FindChildByType<ScrollViewer>(); 

       if (scrollViewer == null) return; 

       if (args.Delta < 0) 
       { 
        scrollViewer.LineRight(); 
       } 
       else 
       { 
        scrollViewer.LineLeft(); 
       } 
      }; 
     } 


     public static void SetUseHorizontalScrolling(ItemsControl element, bool value) 
     { 
      element.SetValue(UseHorizontalScrollingProperty, value); 
     } 

     public static bool GetUseHorizontalScrolling(ItemsControl element) 
     { 
      return (bool)element.GetValue(UseHorizontalScrollingProperty); 
     } 
+0

Это должен быть принятый ответ, +1 для включения кода и ссылок на места, чтобы получить больше кода. Эта реализация работала с первой попытки и чрезвычайно упростила добавление поведения только к элементам управления, к которым я хотел добавить их. – tpartee

Смежные вопросы