我正在尝试让滚动查看器在自定义样式的组框中工作。 这是组框的样式:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!--Set default style of groupbox-->
<Style TargetType="GroupBox">
<Setter Property="Margin" Value="0, 10, 0, 0"></Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="GroupBox">
<Border CornerRadius="4" BorderThickness="1" BorderBrush="{StaticResource BorderBrush}" Background="{StaticResource ContentBackgroundBrush}">
<ScrollViewer HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto">
<StackPanel Orientation="Vertical" CanVerticallyScroll="True">
<Label Content="{TemplateBinding Header}" Margin="5,5,0,0" Style="{StaticResource SmallTitle}"></Label>
<ContentPresenter Margin="10, 5, 10, 10" RecognizesAccessKey="True" x:Name="CtlGroupboxPresenter" />
</StackPanel>
</ScrollViewer>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
出现了滚动条,但无法使用鼠标滚轮滚动。但是,当我的鼠标悬停在垂直滚动条上时,它会起作用。这似乎是一个跟踪问题。
我看到一些人建议在代码后面添加一些代码以使其正常工作,但由于这是在资源字典中,所以我没有地方可以放置它......
有谁知道是什么问题吗?
这是 wpf 表单的图像:
组框内的 XAML:
<UserControl x:Class="Sun.Plasma.Controls.ViewNews"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008">
<DockPanel LastChildFill="True">
<Label DockPanel.Dock="Top" Style="{StaticResource LblTitle}" FontWeight="Bold" FontSize="24" >Latest SUN news & announcements</Label>
<StackPanel Orientation="Vertical" VerticalAlignment="Stretch">
<StackPanel Orientation="Vertical" Name="CtlLoadingNews">
<Label Style="{StaticResource LblContent}">Loading content from server...</Label>
<ProgressBar IsIndeterminate="True" Height="30" />
</StackPanel>
<ListView Background="Transparent" DockPanel.Dock="Bottom" ItemsSource="{Binding NewsFeeds}" BorderBrush="Transparent" Name="CtlNews" Visibility="Collapsed">
<!-- Defining these resources prevents the items from appearing as selectable -->
<ListView.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Transparent" />
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}" Color="Black" />
<SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="Transparent" />
</ListView.Resources>
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical" Margin="0 0 0 20">
<Label Style="{StaticResource LblTitle}" FontWeight="Bold" Content="{Binding Title}" />
<StackPanel Orientation="Horizontal">
<Label Style="{StaticResource LblFooter}" Content="{Binding PublishDate}" />
<Label Style="{StaticResource LblFooter}">By</Label>
<Label Style="{StaticResource LblFooter}" Content="{Binding Authors[0]}" />
<Label Style="{StaticResource LblFooter}">
<Hyperlink RequestNavigate="Hyperlink_RequestNavigate" NavigateUri="{Binding Source}">Read entry</Hyperlink>
</Label>
</StackPanel>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackPanel>
</DockPanel>
问题在于,
ListView
内容中的GroupBox
阻止了MouseWheel
事件冒泡到ScrollViewer
。我找到了一个 hacky 解决方案:
您可以处理内部
PreviewMouseWheel
上的 ListView
事件,并直接在滚动查看器上引发 MouseWheel
事件。
private void ListView_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
{
if (!e.Handled)
{
e.Handled = true;
var eventArg = new MouseWheelEventArgs(e.MouseDevice, e.Timestamp, e.Delta);
eventArg.RoutedEvent = UIElement.MouseWheelEvent;
eventArg.Source = sender;
//navigate to the containing scrollbar and raise the MouseWheel event
(((sender as ListView).Parent as GroupBox).Content as ListView).RaiseEvent(eventArg);
}
}
再次强调,这不是我特别喜欢的解决方案,因为它依赖于
GroupBox
的布局。
第二种稍微好一点的方法是向
GroupBox
的资源添加样式,在其中向 PreviewMouseWheel
事件添加处理程序:
<GroupBox Header="test">
<GroupBox.Resources>
<Style TargetType="ScrollViewer">
<EventSetter Event="PreviewMouseWheel" Handler="ScrollViewer_PreviewMouseWheel" />
</Style>
</GroupBox.Resources>
<!-- your contents -->
</GroupBox>
事件处理程序然后执行滚动:
private void ScrollViewer_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
{
var scrollViewer = sender as ScrollViewer;
double change = e.Delta;
double currentPosition = scrollViewer.VerticalOffset;
scrollViewer.ScrollToVerticalOffset(currentPosition - change);
}
受到@Domysee的启发,但我的事件不是由滚动查看器触发的,可能是因为布局不同
XAML:
<GroupBox Header="Services">
<Grid PreviewMouseWheel="OnScroll">
<ScrollViewer x:Name="_scrollViewer" VerticalScrollBarVisibility="Auto">
<StackPanel Orientation="Vertical">
<ScrollViewer VerticalScrollBarVisibility="Auto">
<ItemsControl ItemsSource="{Binding Services}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="2" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</ScrollViewer>
<Button Width="50"
HorizontalAlignment="Left"
Command="{Binding NewServiceCommand}"
Content="+" />
</StackPanel>
</ScrollViewer>
<Grid
<!-- overlay goes here -->
</Grid>
</Grid>
</GroupBox>
背后代码:
private void OnScroll(object sender, MouseWheelEventArgs e)
{
double change = e.Delta;
double currentPosition = _scrollViewer.VerticalOffset;
_scrollViewer.ScrollToVerticalOffset(currentPosition - change);
}