0

我有一个 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 属性”。我试图“伪造”一个路由事件,但不知道该怎么做。

任何帮助表示赞赏。哦,我是新来的,所以如果我违反礼仪请告诉我。

4

0 回答 0