让事件从 children 向上冒泡

Make an event bubble up from the children upwards

AFAIK 冒泡意味着如果在 children 上触发了一个事件,同样的事件将在 parents.

上触发

我有这段代码:

<ListView Name="lvFiles" SelectedItem="{Binding SelectedTabFilePath, Mode=OneWayToSource, UpdateSourceTrigger=PropertyChanged}"
          ItemsSource="{Binding Path=SelectedItem.Files,ElementName=trvFiles, Mode=OneWay}">
    <ListView.ItemTemplate>
        <DataTemplate>
            <Button Content="{Binding Path=Name}"
                    Command="{Binding DataContext.OpenFileFromTreeView,
                    RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListView}}}"
                    CommandParameter="{Binding DataContext,
                    RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListView}}}"
                    Background="Transparent"
                    BorderBrush="Transparent"
                    >
            </Button>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

问题是,如果我点击按钮,SelectedItem中的属性 SelectedTabFilePath将不会被填充数据(因为我没有点击ListView).

所以,我的问题是: 有什么方法可以触发按钮的 Click 事件和 ListView 的事件吗?

或者如果没有,当我也单击该按钮时,从 SelectedItem 属性设置 SelectedTabFilePath 的方法是什么?

how to handle WPF listbox selectionchanged event using MVVM

我认为您可以在列表框选择更改时使用交互来触发相同的命令 (OpenFileFromTreeView)。

而不是:

AncestorType={x:Type ListView}

如果你尝试会怎么样:

AncestorType={x:Type ListViewItem}

Click event is indeed bubbling, which means it will be routed up the elements of visual tree until the root element is reached. However, the Button itself handles the event,因为其Command属性被绑定了。这意味着它的父元素,包括 ListViewItem(项目容器)将忽略事件,因此不会 select 项目。

有一个变通方法是利用 Button 在单击时获得键盘焦点这一事实。您可以添加一个带有触发器的项目容器样式,一旦键盘焦点位于 IsKeyboardFocusWithin 属性 内,便会设置 ListViewItemIsSelected 属性。

<ListView ...>
   <ListView.ItemContainerStyle>
      <Style TargetType="{x:Type ListViewItem}">
         <Style.Triggers>
            <Trigger Property="IsKeyboardFocusWithin" Value="True">
               <Setter Property="IsSelected" Value="True"/>
            </Trigger>
         </Style.Triggers>
      </Style>
   </ListView.ItemContainerStyle>
   <!-- ...your other markup. -->
</ListView>