具有嵌套 ListView 双击事件的 ListView 会触发两次

ListView with nested ListView double click event fires twice

我设置了一个 WPF 应用程序,它显示应用程序的视图列表。

该应用程序使用绑定到 BrowserItem 的可观察集合的 ListView class(具有 Name 和 RelatedViewId 等属性)。

该应用程序有数百个视图,其中一些具有子视图 - 我通过 BrowserItem class 处理了这个问题,其中包含一个名为 'Children' 的 BrowserItem 属性 列表。

我已经设置了事件,因此当用户双击视图时 returns 来自浏览器的视图名称和相关元素 ID Class。

我通过为 ListViewItems 提供一个 TextBlock 和一个 ListView 来处理子视图 - 然后将 listView 绑定到 BrowserItem 的子列表。

这一切都很好:

Capture of application running

我遇到的问题是,当单击子项时,子项和父项 ListItem 的事件都会被触发。

有没有什么方法可以在双击子项目时只为子项目触发双击事件,而不是为它的父容器触发。

继承人 XAML:

<ListView Name="ViewList" ItemsSource="{Binding GroupItems}">

    <ListView.ItemContainerStyle>
        <Style TargetType="ListViewItem">
            <EventSetter Event="MouseDoubleClick"
                         Handler="ViewList_MouseDoubleClick" />
        </Style>
        
    </ListView.ItemContainerStyle>

    <ListView.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                
                <!--This is the child list, it visibility is set to collapsed if the child count = 0-->
                <Expander>
                    <Expander.Style>
                        <Style>
                            <Style.Triggers>
                                <DataTrigger Binding="{Binding Path=Children.Count}"
                                             Value="0">
                                    <Setter Property="Expander.Visibility"
                                            Value="Collapsed" />
                                </DataTrigger>
                            </Style.Triggers>
                        </Style>
                    </Expander.Style>


                    <ListBox ItemsSource="{Binding Children}">
                        <ListBox.ItemTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding Name}" />
                            </DataTemplate>
                        </ListBox.ItemTemplate>
                        <ListBox.ItemContainerStyle>
                            <Style TargetType="ListBoxItem">
                                <EventSetter Event="MouseDoubleClick"
                                             Handler="ViewBox_MouseDoubleClickChild" />
                            </Style>
                        </ListBox.ItemContainerStyle>
                    </ListBox>
                    
                </Expander>

                <TextBlock Text="{Binding Name}">
                    <TextBlock.Style>
                        <Style TargetType="{x:Type TextBlock}">
                            <Style.Triggers>
                                <DataTrigger Binding="{Binding Active}"
                                             Value="true">
                                    <Setter Property="Background"
                                            Value="YellowGreen" />
                                </DataTrigger>
                            </Style.Triggers>
                        </Style>
                    </TextBlock.Style>
                </TextBlock>
                
            </StackPanel>
        </DataTemplate>
    </ListView.ItemTemplate>

    <ListView.GroupStyle>
        <GroupStyle>
            <GroupStyle.ContainerStyle>
                <Style TargetType="{x:Type GroupItem}">
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate>
                                <Expander>
                                    <Expander.Header>
                                        <TextBlock Text="{Binding Name}" />
                                    </Expander.Header>
                                    <ItemsPresenter />
                                </Expander>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </GroupStyle.ContainerStyle>
        </GroupStyle>
    </ListView.GroupStyle>

</ListView>

事件调用的背后代码只是获取对象并显示其名称:

单击 ListItem 时的事件:

private void ViewList_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{

    ListViewItem picklv = sender as ListViewItem;

    BrowserItem chosen = picklv.Content as BrowserItem;

    MessageBox.Show("Clicked on View: " + chosen.Name + " Element Id: " + chosen.RelatedElement.ToString());

}

单击“查看子项”列表中的子项时的事件:

private void ViewBox_MouseDoubleClickChild(object sender, MouseButtonEventArgs e)
{
    ListBoxItem picklb = sender as ListBoxItem;

    BrowserItem pickedsub = picklb.Content as BrowserItem;

    MessageBox.Show("Clicked on Child View: " + pickedsub.Name + " Element Id: " + pickedsub.RelatedElement.ToString());
}

通过子元素你必须监听 PreviewMouseDoubleClick

<EventSetter Event="PreviewMouseDoubleClick" Handler="ViewBox_MouseDoubleClickChild" />

并在子事件处理程序中添加 e.Handled = true;:

private void ViewBox_MouseDoubleClickChild(object sender, MouseButtonEventArgs e)
{
    var picklb = sender as ListBoxItem;

    var pickedsub = picklb.Content as BrowserItem;

    MessageBox.Show("Clicked on Child View: " + pickedsub.Name + " Element Id: " + pickedsub.RelatedElement.ToString());

    e.Handled = true;
}

这将防止调用父元素的 MouseDoubleClick 事件处理程序。