如何启用鼠标水平滚动?

发布于 2024-09-24 04:39:34 字数 2988 浏览 1 评论 0原文

我无法确定如何使用鼠标滚轮水平滚动。垂直滚动可以自动很好地工作,但我需要水平滚动我的内容。我的代码如下所示:

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

我需要添加其他方法或控件才能获得该功能吗?

I cannot determine how to scroll horizontally using the mouse wheel. Vertical scrolling works well automatically, but I need to scroll my content horizontally. My code looks like this:

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

My item template looks like this:

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

Is there another method or control that I need to add to get that functionality?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

慕烟庭风 2024-10-01 04:39:35
(sender as ScrollViewer).ScrollToHorizontalOffset( (sender as ScrollViewer).ContentHorizontalOffset    + e.Delta);
(sender as ScrollViewer).ScrollToHorizontalOffset( (sender as ScrollViewer).ContentHorizontalOffset    + e.Delta);
紫轩蝶泪 2024-10-01 04:39:35

试试这个:

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

更新 哎呀,错过了关于鼠标滚轮的部分!抱歉,

要使鼠标滚轮工作,您必须订阅鼠标滚轮事件并手动移动滚动条...这可以很好地封装为行为,但我认为这是使其工作的唯一方法!

Try this:

<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 Ooops, missed the part about the mouse wheel! Sorry

To make the mouse wheel work, you will have to subscribe to the mouse wheel event and manuaaly move the scroll bar... This can nicelly be encapsulated by a behavior but I think thats the only way to make it work!

寻梦旅人 2024-10-01 04:39:34

这是一个完整的行为。将以下类添加到您的代码中,然后在 XAML 中将任何包含 ScrollViewer 作为可视子项的 UIElement 的附加属性设置为 true。

<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(UIElement element, bool value) => element.SetValue(ShiftWheelScrollsHorizontallyProperty, value);
    public static bool GetShiftWheelScrollsHorizontally(UIElement 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 的答案 中的一些错误,例如不按 Shift 键进行过滤、水平滚动和同时垂直(运动是对角线)并且无法通过将属性设置为 false 来禁用该行为。

Here's a complete behaviour. Add the below class to your code, then in your XAML set the attached property to true on any UIElement that contains a ScrollViewer as a visual child.

<MyVisual ScrollViewerHelper.ShiftWheelScrollsHorizontally="True" />

The class:

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(UIElement element, bool value) => element.SetValue(ShiftWheelScrollsHorizontallyProperty, value);
    public static bool GetShiftWheelScrollsHorizontally(UIElement 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;
    }
}

This answer fixes a few bugs in Johannes' answer, such as not filtering by Shift key, scrolling both horizontally and vertically at the same time (motion was diagonal) and the inability to disable the behaviour by setting the property to false.

扛刀软妹 2024-10-01 04:39:34

为此,我编写了一个附加属性,以便在每个包含 ScrollViewer 的 ItemsControl 上重用它。 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);
        }

I wrote an Attached Property for this purpose to reuse it on every ItemsControl containing an ScrollViewer. FindChildByType is an Telerik extension but can also be found 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);
        }
一瞬间的火花 2024-10-01 04:39:34

我有点寻找最简单的方法来使任何 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;
}

这基本上就是 John Gardner 建议的实际代码。我还引用了我在类似问题中的回答。

I was kinda looking for the most simple way to make any ScrollViewer scroll left-right instead of up-down. So here is the simplest combination of the other answers.

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

and:

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

This is basically what John Gardner suggested just with the actual code. I'm also quoting my answer from similar question here.

爱人如己 2024-10-01 04:39:34

最简单的方法是将 PreviewMouseWheel 侦听器添加到 ScrollViewer,检查是否有平移(或任何您想要指示水平滚动的操作),然后调用 LineLeft< /code> 或 LineRight(或 PageLeft / PageRight),具体取决于 Delta 值的值代码>MouseWheelEventArgs

The easiest way is to add PreviewMouseWheel listener to the ScrollViewer, check for shift (or whatever you want to do to indicate horizontal scroll), and then call LineLeft or LineRight (or PageLeft / PageRight) depending on the value of the Delta value of the MouseWheelEventArgs

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文