当使用 ScrollViewer 作为某些控件模板的一部分时,将处理左键单击
考虑代码的第一个版本 (MainWindow.xaml):
<ScrollViewer>
<local:CustomControl1 Width="1000" Height="1000" Background="Red"/>
</ScrollViewer>
其中 CustomControl1 派生自 ItemsControl。在 CustomControl1 内部,我重写 OnMouseDown 事件。这段代码运行完美,我确实捕获了鼠标按下事件。
现在代码的第二个版本(MainWindow.xaml):
<local:CustomControl1 Width="1000" Height="1000" Background="Red"/>
在Generic.xaml中,我更改了项目控件的模板:
<ControlTemplate TargetType="{x:Type local:CustomControl1}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<ScrollViewer
VerticalScrollBarVisibility="Visible"
HorizontalScrollBarVisibility="Visible"
>
<ItemsPresenter/>
</ScrollViewer>
</Border>
</ControlTemplate>
当我将scrollviewer作为控件模板的一部分时,我不再接收OnMouseDownEvent(左键单击)。由于某种原因,现在鼠标按下事件标记为已处理。如果我不重写 OnMouseDown,而是在项目控件构造函数中使用以下语句,则会捕获该事件:
AddHandler(Mouse.MouseDownEvent, new MouseButtonEventHandler(OnMouseDown), true);
首先,我想了解为什么将scrollviewer 放置在模板中更改鼠标按下的行为。其次,有人知道一些解决方法吗? 我提出的解决方案(通过捕获已处理的事件)对我来说是不可接受的。在我的应用程序中,仅当没有项目控制子项处理鼠标按下事件时,我才需要处理鼠标按下事件。
提前致谢。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
例如,如果查看
ListBox
的默认Template
(它也派生自ItemsControl
),您将看到ScrollViewer
在模板中设置了Focusable="False"
。这允许鼠标事件传递到您的控件If you look at the default
Template
for aListBox
for example (which also derives fromItemsControl
), you'll see that theScrollViewer
hasFocusable="False"
set in the Template. This allows the mouse events to pass through to your control至于正在处理的事件,根本原因是当
ScrollViewer
可聚焦时,其内部OnMouseLeftButtonDown
方法将尝试获取焦点,如果成功,处理事件。这是 VS2019 反编译的代码:
因此一种方法是设置
Focusable="False"
(如 阻止启动键绑定。但如果它有重点,它们就会起作用。因此,另一种更灵活的方法是添加一个事件处理程序,如下所示:
handler
的作用是:或者,如果您碰巧要创建自己的派生 ScrollViewer,则只需重写
OnMouseLeftButtonDown
即可。As regards the event being handled, a root cause is that when a
ScrollViewer
is focusable, its internalOnMouseLeftButtonDown
method will try to get focus and if it succeeds, it handles the event.Here's the very code from the VS2019 decompilation:
So one method is to set
Focusable="False"
(as noted in the other answer) because it prevents this from occurring. But that might be too extreme or restrictive (it was for me). For example, I found that preventing myScrollViewer
from receiving focus would stop keybindings from being initiated. But if it had focus, they would work.So another more flexible approach is to add an event handler like so:
Where
handler
just does:Or if you happen to be creating your own derived ScrollViewer you can just override
OnMouseLeftButtonDown
.