BradStevenson
BradStevenson

Reputation: 1994

Preventing tapped events propagating to parent elements xaml

I'm creating a WP8.1 app using C# and XAML

I have a ListView in which the ListViewItems contains a TextBlock.

The TextBlocks have Tapped="" event handlers, however I want to stop the cell being selected when one of these TextBlocks are tapped.

Setting TappedRoutedEventArgs.Handled = true; is not stopping the ListViewItem being selected.

(Because of the hierarchy I cannot traverse throught the TextBlocks parent elements to get the ListViewContainer).

What would be the best way to go about this?

Upvotes: 5

Views: 3908

Answers (5)

galactic.fungus
galactic.fungus

Reputation: 486

I had the same problem with a custom control that was on a ListViewItem. I overrode the OnPointerPressed event and mark it as handled in addition to the tapped event and this stopped the listview from receiving the selection event.

protected override void OnPointerPressed(PointerRoutedEventArgs e)
{
  base.OnPointerPressed(e);
  e.Handled = true;
}

The above will work when deriving your own control, but you can just hook the events on any control and mark them as handled something like

<TextBlock Text="whatever" Tapped="UIElement_OnTapped"
    PointerPressed="UIElement_OnPointerPressed"/>

and then in code

private void UIElement_OnTapped(object sender, TappedRoutedEventArgs e)
{
  e.Handled = true;
}

private void UIElement_OnPointerPressed(object sender, PointerRoutedEventArgs e)
{
  e.Handled = true;
}

Upvotes: 1

Lu&#237;s Ledebour
Lu&#237;s Ledebour

Reputation: 35

Use property IsHitTestVisible="False" on the control. Mouse events will pass through it.

Upvotes: 2

Vlad
Vlad

Reputation: 873

Ok, here's how I solved this problem.

XAML:

<ListView IsItemClickEnabled="True" ItemClick="ItemClickHandler" SelectionMode="None">
   <ListView.ItemTemplate>
      <DataTemplate>
         <TextBlock Text="SomeText" Tapped="TextTapped" />
      </DataTemplate>
   </ListView.ItemTemplate>
</ListView>

C#

private bool IsItemClickDisabled;

private void TextTapped(object sender, TappedRoutedEventArgs e)
{
   IsItemClickDisabled = true;
   //TODO: Your tap event handler

   e.Handled = true;
}

private async void ItemClickHandler(object sender, ItemClickEventArgs e)
{
   IsItemClickDisabled = false; //Reset each time
   await System.Threading.Tasks.Task.Delay(TimeSpan.FromMilliseconds(1));
   if (!IsItemClickDisabled)
   {
      //TODO: ItemClick handler
   }
}

So, generally, ItemClickHandler will be executed first, but we delay this event, so another events can execute. If any tapped event was executed, we just say: "Ok, we gonna execute this code, no need to execute ItemClick event."

Upvotes: 2

Romasz
Romasz

Reputation: 29792

If you don't want to select you ListView items, I think you can try to do it with a help of IsItemClickEnabled property:

By default, a user can select items in the view by tapping or clicking on them. You can change this behavior to make the user interaction fire a click event instead of triggering item selection.

If you set the IsItemClickEnabled property to true, you must set the SelectionMode property to ListViewSelectionMode.None. Handle the ItemClick event to respond to the user interaction.

Upvotes: 0

Muhammad Saifullah
Muhammad Saifullah

Reputation: 4292

When tapped on textblock listview selection changed event is raised before the textblock tap event(so 1. SelectionChanged event than text block tap). That is way selected item changed event will always be fired in case of textblock tap. and if we use button controls(any control that has some tap operation) it will raise the button tap event BUT will not raise selection changed event.

in your case you can implement some hack. like continue with the selection in selection changed event and revert the selection when event reach the textblock tap event.

Hope this helps

Upvotes: 0

Related Questions