Как включить горизонтальную прокрутку с помощью мыши? - PullRequest
12 голосов
/ 16 сентября 2010

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

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

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

Ответы [ 6 ]

8 голосов
/ 01 октября 2014

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

 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);
        }
7 голосов
/ 05 февраля 2017

Вот полное поведение.Добавьте приведенный ниже класс к своему коду, затем в своем 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;
    }
}

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

7 голосов
/ 10 мая 2011

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

4 голосов
/ 01 марта 2014
(sender as ScrollViewer).ScrollToHorizontalOffset( (sender as ScrollViewer).ContentHorizontalOffset    + e.Delta);
0 голосов
/ 09 ноября 2018

Я искал самый простой способ сделать любую прокрутку ScrollViewer влево-вправо, а не вверх-вниз.Итак, вот простейшая комбинация других ответов.

<ScrollViewer HorizontalScrollBarVisibility="Visible"
              PreviewMouseWheel="ScrollViewer_PreviewMouseWheel"> 

и:

private void ScrollViewer_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
{
    ScrollViewer scrollViewer = (ScrollViewer)sender;
    if (e.Delta < 0)
    {
        scrollViewer.LineRight();
    }
    else
    {
        scrollViewer.LineLeft();
    }
    e.Handled = true;
}

Это в основном то, что Джон Гарднер предложил только с фактическим кодом.Я также цитирую свой ответ от аналогичного вопроса здесь .

0 голосов
/ 16 сентября 2010

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

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

ОБНОВЛЕНИЕ Упс, пропустил часть о колесе мыши! К сожалению

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...