在我的应用程序中,当用户尝试单击主窗口上的滑块时,弹出控件处于打开状态时,弹出控件会窃取鼠标按下事件。 这会导致滑块无法正确响应鼠标按下事件。 (它似乎得到焦点并转移到一个不正确的位置)
我发现" OnPreviewMouseLeftButtonDown"弹出窗口中的滑块不会触发" StaysOpen"属性为false(弹出窗口打开), 并且当它的真实时(或当弹出窗口关闭时)触发。
我想知道是否有人找到了解决此问题的方法。
我在各种环境中的应用程序的其他控件中遇到了这些类型的问题,所以我更喜欢一个更通用的解决方案,而不仅仅是为滑块解决这个问题。
示例代码:
<Window x:Class="SampleApplication.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Name="Root"
Title="MainWindow" Height="350" Width="525">
<Grid Height="130" Width="300">
<Button Width="40" Height="40" Click="ButtonBase_OnClick" HorizontalAlignment="Left" VerticalAlignment="Top"></Button>
<Popup StaysOpen="False" IsOpen="{Binding ElementName=Root, Path=IsOpen}" Width="100" Height="100"
HorizontalAlignment="Center" VerticalAlignment="Center" Placement="Center">
<Grid Background="Black">
<TextBlock Text="hello"></TextBlock>
</Grid>
</Popup>
<Slider Width="200" IsMoveToPointEnabled="True" VerticalAlignment="Bottom"></Slider>
</Grid>
非常感谢, Yotam
答案 0 :(得分:1)
这是因为PreviewMouseDown
(及其衍生物)(来自基类UIElement
)具有默认RoutingStrategy.Direct
。
直接 - 路由事件不通过元素树进行路由,但支持其他路由事件功能,如类处理,EventTrigger或EventSetter。
这是从ReferenceSource获取的事件的源代码。
public static readonly RoutedEvent PreviewMouseLeftButtonDownEvent =
EventManager.RegisterRoutedEvent(
"PreviewMouseLeftButtonDown",
RoutingStrategy.Direct,
typeof(MouseButtonEventHandler),
_typeofThis);
以下是Popup
:
private void OnPreviewMouseButton(MouseButtonEventArgs e)
{
// We should only react to mouse buttons if we are in an auto close mode (where we have capture)
if (_cacheValid[(int)CacheBits.CaptureEngaged] && !StaysOpen)
{
Debug.Assert( Mouse.Captured == _popupRoot.Value, "_cacheValid[(int)CacheBits.CaptureEngaged] == true but Mouse.Captured != _popupRoot");
// If we got a mouse press/release and the mouse isn't on the popup (popup root), dismiss.
// When captured to subtree, source will be the captured element for events outside the popup.
if (_popupRoot.Value != null && e.OriginalSource == _popupRoot.Value)
{
// When we have capture we will get all mouse button up/down messages.
// We should close if the press was outside. The MouseButtonEventArgs don't tell whether we get this
// message because we have capture or if it was legit, so we have to do a hit test.
if (_popupRoot.Value.InputHitTest(e.GetPosition(_popupRoot.Value)) == null)
{
// The hit test didn't find any element; that means the click happened outside the popup.
SetCurrentValueInternal(IsOpenProperty, BooleanBoxes.FalseBox);
}
}
}
}
所以它被设计为以这种方式工作,你可能不会使用OnPreviewMouseDown
来完成你想要在这里完成的任何事情。
答案 1 :(得分:0)
在我的应用程序中,当用户尝试单击主窗口上的滑块时,弹出控件打开时,弹出控件会窃取鼠标按下事件
虽然您的描述不完全正确,但这是任何Popup
控件的正常行为。发生这种情况的原因是因为Popup
控件具有焦点,因此它正在侦听Click
事件,即使它发生在Popup
。现在从逻辑上考虑一下......如果它没有这样做,它怎么知道何时关闭?您会在Popup
中使用的ComboBox
控件中找到相同的行为。
答案 2 :(得分:0)
有一种解决方法可以实现您需要的行为,为您使用的Slider控件设置' IsHitTestVisible = True '。
<强> PS:强> 设置IsHitTestVisible = True,仅在弹出窗口打开时 - 否则为假。