Make an event bubble up from the children upwards

409 views Asked by At

AFAIK bubbling means that if an event is triggered on the children, the same event will be triggered on the parents.

I have this piece of code:

<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>

The problem is that if I click on the button, the property SelectedTabFilePath from SelectedItem will not be filled with data (because I didn't click on the item of the ListView).

So, my question is: Is there any way to trigger the Click event of the button and that of the ListView too?

Or if not, what would be the way to set the SelectedTabFilePath from the SelectedItem attribute when I click on that button, too?

3

There are 3 answers

0
thatguy On BEST ANSWER

The 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, because its Command property was bound. That means its parent elements, including ListViewItem (the item container) will ignore the event, therfore not select the item.

There is a workaround using the fact that the Button receives keyboard focus upon clicking. You add an item container style with a trigger that sets the IsSelected property of the ListViewItem once the keyboard focus is within, denoted by the IsKeyboardFocusWithin property.

<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>
1
John Schruben On

how to handle WPF listbox selectionchanged event using MVVM

I think you could use interaction to trigger the same command(OpenFileFromTreeView) when the listbox selection changes.

1
AMA On

Instead of:

AncestorType={x:Type ListView}

What if you try:

AncestorType={x:Type ListViewItem}