我在滚动WPF应用程序时出现问题。
这是合约。我的用户界面如下:
我的应用程序的作用是充当许多应用程序的中心枢纽并启动它们。管理员可以启动另一个用户记录的转储。
因此,我有一个ListView
,显示应用程序列表,如果需要可以滚动。
我定义了GroupStyle
以显示扩展器并模拟Windows资源管理器视图。
一切正常,我只是有一个问题:当用鼠标滚轮滚动时,组件以蓝色清晰(“启动模式”)似乎正在捕捉焦点并停止滚动。
这尤其意味着如果我的鼠标在此控件之外的任何地方,滚动就可以了。但只要鼠标进入此控件,我就不能再滚动了。
我尝试修改属性Focusable
并将其设置为False
我无处可去,但没有任何改变。我猜它最终不是焦点问题。
任何人都知道如何避免元素捕获滚动?
以下是一些(简化,删除了一些无用的属性,以使其尽可能清晰)XAML用于扩展器的内容:
<StackPanel Orientation="Vertical" VerticalAlignment="Top" >
<ToggleButton>
<!-- ToggleButton Content... -->
</ToggleButton>
<!-- This is the custom component in which you can see "Launch mode" -->
<my:UcReleaseChooser >
<!-- Properties there. I tried to set Focusable to False, no impact... -->
</my:UcReleaseChooser>
</StackPanel>
UcReleaseChooser
的代码:
<StackPanel HorizontalAlignment="Stretch"
Focusable="False" ScrollViewer.CanContentScroll="False">
<ListBox ItemsSource="{Binding ListChosenReleases}" BorderBrush="LightGray" Background="AliceBlue"
HorizontalAlignment="Stretch" Focusable="False" ScrollViewer.CanContentScroll="False">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical"
Focusable="False" ScrollViewer.CanContentScroll="False"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<DockPanel LastChildFill="True" HorizontalAlignment="Stretch"
Focusable="False" ScrollViewer.CanContentScroll="False">
<TextBlock DockPanel.Dock="Top"
HorizontalAlignment="Left" Text="{Binding Key}"
FontStyle="Italic"/>
<ListBox DockPanel.Dock="Bottom"
HorizontalAlignment="Right" ItemsSource="{Binding Value}"
BorderBrush="{x:Null}" Background="AliceBlue"
Focusable="False" ScrollViewer.CanContentScroll="False">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Focusable="False"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<-- Blah blah about style -->
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<RadioButton Content="{Binding Key}" Margin="3"
IsChecked="{Binding Path=IsSelected, Mode=TwoWay,
RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type ListBoxItem}}}"
Focusable="False" ScrollViewer.CanContentScroll="False"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</DockPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
如您所见,UcReleaseChooser
包含RadioButton
列表的列表。我试图设置Focusable
&amp; CanContentScroll
到False
到处看似合适,但控件一直阻止主UI滚动......
我想我应该改变另一个属性......任何想法?
谢谢!
答案 0 :(得分:1)
问题在于ListBox
,或更具体地说,是ScrollViewer
模板中的ListBox
。这是获取滚动事件并在ScrollViewer
中的外ListView
甚至看到它们之前使用它们。
如果可能的话,我建议用ListBox
替换ItemsControl
。但是,这意味着不会有SelectedItem
属性。如果您需要,我建议您将ScrollViewer.HorizontalScrollBarVisibility
(或VerticalScrollBarVisibility
)设置为Disabled
。如果做不到这一点,我只能建议重新模板ListBox
根本不包含ScrollViewer
。
答案 1 :(得分:1)
我遇到了一个列表框在滚动查看器中窃取焦点的问题(我在scrollviewer中有多个列表框)。所以我创建了一个附加属性,它拒绝列表框滚动的能力。因此,容纳列表框的滚动查看器可以滚动
您的控件是一个列表框,因此这应该按原样运行,但没有理由将扩展名限制为列表框;它只是为了符合我的确切目的。
public static class ListboxExtensions
{
public static DependencyProperty IgnoreScrollProperty = DependencyProperty.RegisterAttached("IgnoreScroll", typeof(bool), typeof(ListboxExtensions), new UIPropertyMetadata(false, IgnoreScrollChanged));
public static bool GetIgnoreScroll(DependencyObject dependencyObject)
{
return (bool)dependencyObject.GetValue(IgnoreScrollProperty);
}
public static void SetIgnoreScroll(DependencyObject dependencyObject, bool value)
{
dependencyObject.SetValue(IgnoreScrollProperty, value);
}
private static void IgnoreScrollChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var newValue = (bool)e.NewValue;
var oldValue = (bool)e.OldValue;
var frameworkElement = d as FrameworkElement;
if (frameworkElement == null) return;
if (!newValue || oldValue || frameworkElement.IsFocused) return;
var lb = frameworkElement as ListBox;
if (lb == null) return;
lb.PreviewMouseWheel += LbOnPreviewMouseWheel;
}
private static void LbOnPreviewMouseWheel(object sender, MouseWheelEventArgs e)
{
if (!(sender is ListBox) || e.Handled) return;
e.Handled = true;
var eventArg = new MouseWheelEventArgs(e.MouseDevice, e.Timestamp, e.Delta)
{
RoutedEvent = UIElement.MouseWheelEvent,
Source = sender
};
var parent = ((Control)sender).Parent as UIElement;
if (parent != null) parent.RaiseEvent(eventArg);
}
}
然后在你的XAML中,你只需将它放在列表框中:
<ListBox extensions:ListboxExtensions.IgnoreScroll="True">
当然,请记住在XAML顶部的扩展名中包含命名空间:
xmlns:extensions="clr-namespace:UI.Extensions"