我有一个 ListBox 使用的 DataTemplate 来为每个 ListBoxItem 提供“外观”。此外,由于这些 ListBoxItem 可以比它们所在的列宽,如果鼠标悬停在该项目上,我还会在 ListBoxItem 的顶部绘制一个弹出窗口。Popup 使用与其覆盖的项目相同的 ContentTemplate,因此外观是鼠标下的项目只是停止剪切到它所在的 ListBox 的边界。它运行良好,但我无法成功地将鼠标事件传递回控件是模糊的,以便底层控件可以检测到拖动操作开始。
<!--This datatemplate is used to create a popup over the listboxitem in ItemsView.xaml-->
<DataTemplate x:Key="PopupDaybookItemDataTemplate">
<StackPanel x:Name="pdidt">
<Popup x:Name="myPopup" PlacementTarget="{Binding RelativeSource={RelativeSource AncestorType=ListBoxItem}}" Placement="Relative" StaysOpen="True">
<Popup.Style>
<Style TargetType="{x:Type Popup}">
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding ElementName=myPopup, Path=IsMouseOver}" Value="True" />
</MultiDataTrigger.Conditions>
<Setter Property="IsOpen" Value="True" />
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding Mode=OneWay, ElementName=pdidt, Path=IsMouseOver}" Value="True" />
</MultiDataTrigger.Conditions>
<Setter Property="IsOpen" Value="True" />
</MultiDataTrigger>
</Style.Triggers>
</Style>
</Popup.Style>
<ListBoxItem Style="{StaticResource DayBookItemStyle}"
PreviewMouseDown="ItemListPopup_OnMouseButtonEvent"
MouseDown="ItemListPopup_OnMouseButtonEvent"
PreviewMouseMove="ItemListPopup_OnMouseEvent"
MouseMove="ItemListPopup_OnMouseEvent"
>
<ContentPresenter ContentTemplate="{StaticResource DaybookItemDataTemplate}"
PreviewMouseDown="ItemListPopup_OnMouseButtonEvent"
MouseDown="ItemListPopup_OnMouseButtonEvent"
PreviewMouseMove="ItemListPopup_OnMouseEvent"
MouseMove="ItemListPopup_OnMouseEvent"
/>
</ListBoxItem>
</Popup>
<ContentPresenter x:Name="MyItemPresenter" ContentTemplate="{StaticResource DaybookItemDataTemplate}" ></ContentPresenter>
</StackPanel>
</DataTemplate>
请注意与弹出窗口中的 ListBoxItem 和 ContentPresenter 相关的事件。它们与以下代码隐藏相关联:
private void ItemListPopup_OnMouseButtonEvent(object sender, MouseButtonEventArgs e)
{
Popup popup = (((DependencyObject)sender).GetVisualParent<Popup>());
popup.PlacementTarget.RaiseEvent(e);
}
private void ItemListPopup_OnMouseEvent(object sender, MouseEventArgs e)
{
Popup popup = (((DependencyObject)sender).GetVisualParent<Popup>());
popup.PlacementTarget.RaiseEvent(e);
}
PlacementTarget 是被绘制的 ListBoxItem。ContentPresenter 上的 MouseDown 允许底层 ListViewItem 知道它已被单击并因此被选中,并且工作正常。ListBoxItem 上的 MouseDown 不符合我的预期。(无论 ContentPresenter MouseDown 事件是否被钩住)。其他事件似乎没有执行任何有用的任务,但我将它们包括在内,因为我认为它们是显而易见的尝试。
我希望将 MouseDown 和 MouseMove 事件中继到底层 ListBox 将允许它检测到拖动操作,但事实并非如此。我也尝试过以这种方式传递所有鼠标事件(隧道和冒泡),但拖动操作仍然没有开始。如果 Popup 被(永久)禁用,则底层控件可以完美地检测到拖动操作,但是在鼠标事件中禁用 Popup 并没有帮助。
我尝试将 Popup IsHitTestVisible 设置为 false 但这无济于事 - 我猜是因为 Popup 是一个单独的窗口而不是可视树的一部分,因此没有任何地方可以让事件冒泡?
我也尝试过更改 mouseEvent.Source,但出现运行时错误“在路由事件时无法更改 RoutedEvent 属性”。我试图“伪造”一个路由事件,但不知道该怎么做。
任何帮助表示赞赏。哦,我是新来的,所以如果我违反礼仪请告诉我。