我无法确定如何使用鼠标滚轮水平滚动。垂直滚动可以自动运行,但我需要水平滚动我的内容。我的代码如下所示:
<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 :(得分:8)
我为此目的写了一个Attached Property
,以便在包含ScrollViewer的每个ItemsControl
上重复使用它。 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);
}
答案 1 :(得分:7)
最简单的方法是将PreviewMouseWheel
侦听器添加到ScrollViewer
,检查shift(或者您要执行的任何操作以指示水平滚动),然后调用LineLeft
或{{ 1}}(或LineRight
/ PageLeft
),具体取决于PageRight
Delta
值的值
答案 2 :(得分:7)
这是一个完整的行为。将以下类添加到您的代码中,然后在您的XAML中,在包含UIElement
作为可视子项的任何ScrollViewer
上将附加属性设置为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(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键过滤,同时水平和垂直滚动(动作是对角线),并且无法通过将属性设置为禁用行为假的。
答案 3 :(得分:4)
(sender as ScrollViewer).ScrollToHorizontalOffset( (sender as ScrollViewer).ContentHorizontalOffset + e.Delta);
答案 4 :(得分: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 哎呀,错过了关于鼠标滚轮的部分!遗憾
要使鼠标滚轮工作,您必须订阅鼠标滚轮事件并手动移动滚动条...这可以通过行为进行封装,但我认为这是使其工作的唯一方法!< / p>
答案 5 :(得分:0)
我一直在寻找最简单的方法来使任何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 suggested就是实际代码。我还引用了similar question here的答案。