Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 996
BradStevenson Avatar asked Jun 02 '14 23:06

BradStevenson


3 Answers

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

like image 160
Vlad Avatar answered Nov 18 '22 20:11

Vlad


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

like image 42
Luís Ledebour Avatar answered Nov 18 '22 21:11

Luís Ledebour


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;
}
like image 1
galactic.fungus Avatar answered Nov 18 '22 19:11

galactic.fungus