0
votes

Seems like this would be a common problem...

I'm using MVVM Light

I have a listbox defined in my xaml

<ListBox ItemsSource="{Binding Events}" SelectedItem="{Binding SelectedEvent, Mode=TwoWay}">

    <i:Interaction.Triggers>
        <i:EventTrigger EventName="Tap">
            <cmd:EventToCommand Command="{Binding EventPageCommand, Mode=OneWay}"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>

    <ListBox.ItemTemplate>
        <DataTemplate>
            <Border Padding="0,0,0,22">
                <StackPanel>
                    <TextBlock Text="{Binding Name}" />
                    <TextBlock Text="{Binding Preview}" TextWrapping="Wrap"/>
                </StackPanel>
            </Border>
        </DataTemplate>

     </ListBox.ItemTemplate>
 </ListBox>

This works all fine and dandy, except the user is able to click below this list and the event is still fired.

I can modify it to use SelectionChanged such as:

<i:Interaction.Triggers>
    <i:EventTrigger EventName="SelectionChanged">
        <cmd:EventToCommand Command="{Binding EventPageCommand, Mode=OneWay}"/>
    </i:EventTrigger>
</i:Interaction.Triggers>

But then if I use the back button, I cannot select the same item twice since the selection hasn't actually changed. I could probably go into my codebehind and set the selected index = -1 on page load, but this seems like quite a hack, and I use list boxes in quite a few places and I would hate to have to remember to do this hack everywhere.

Any ideas?

edit
I added background color to my listbox and my listbox items and while my listbox items only take up what space the text occupies, the listbox takes up the entire screen, extending below the last listbox item. Perhaps one way would be to shore up this extra space.

update
what seems to work best so far is to set the VerticalAlignmnet="Top" on the listbox (this shores up the extra space on the bottom, not sure why, but then scrolling ends at the bottom of the list and not the bottom of the screen). I then disabled the scrolling on the listbox itself ScrollViewer.VerticalScrollBarVisibility="Disabled" and wrapped the whole thing in a <ScrollViewer>

2
FWIW, I had a similar problem and ended up setting the SelectedIndex to -1 in the event handler right before navigating to a new page.Praetorian

2 Answers

1
votes

Currently you are looking for the Tap event on the whole of the list box, not a individual item.

This is how I typically I use interaction triggers:

<DataTemplate DataType="{x:Type ViewModel:DataItem}" x:Key="ItemTemplate">
    <ContentControl>
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="Tap">
                <i:InvokeCommandAction Command="{Binding Tap}"/>
            </i:EventTrigger>
            <i:EventTrigger EventName="KeyUp">
                <i:InvokeCommandAction 
                   Command="{Binding RelativeSource={RelativeSource 
                             Mode=FindAncestor, 
                             AncestorType={x:Type ListBox}}, 
                             Path=DataContext.KeyUpCommand}"/>
            </i:EventTrigger>
        </i:Interaction.Triggers>
        <TextBox Text="{Binding Name}"/>
    </ContentControl>
</DataTemplate>

In this example the Tap event binds to a command on the DataContext (a data item) of an ItemsControl, whereas the KeyUp event binds to a command on the parent DataContext of the ListBox.

0
votes

If all you want is to get an event when the user taps an item, why don't you use the trigger code you have on the Border element of the template?

You probably will have to use the Source property to bind the command to the ViewModel, but that can also be easely achieved (will just depend on how you are setting the Page DataContext right now)