【问题标题】:ListView with nested ListView double click event fires twice带有嵌套 ListView 双击事件的 ListView 触发两次
【发布时间】:2021-04-23 02:33:18
【问题描述】:

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

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

该应用程序有数百个视图,其中一些有子视图 - 我已经通过 BrowserItem 类处理了这个问题,该类有一个名为“Children”的 BrowserItem 属性列表。

我已经设置了事件,所以当用户双击视图时,它会从浏览器类返回视图名称和相关元素 ID。

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

这一切都很好:

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());
}

【问题讨论】:

  • 双击事件是在 ListBox.ItemContainerStyle 中使用 Style 标记和 EventSetter 处理的(根据您引用的帖子中的第一段代码)。我已经更新了上面的问题以包含这个,以及后面的代码。

标签: wpf listview events listbox


【解决方案1】:

通过子元素你必须监听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 事件处理程序。

【讨论】:

  • 优秀——正是我想要的!谢谢。我会点击回答按钮,但显然我不能,因为我的代表低于 15...
  • @Archie456 您可以接受任何声誉的问题,只需点击灰色钩子,但赞成您只能使用 >=15。
猜你喜欢
  • 2010-11-05
  • 2011-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-21
  • 1970-01-01
  • 1970-01-01
  • 2014-05-28
相关资源
最近更新 更多