2

I have this listview:

<Page
    x:Class="DataBase.ControlsPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    DataContext="{Binding CustomersViewModel, Source={StaticResource ViewModelLocator}}">

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <ListView Name="HeaderList" ItemsSource="{Binding Customers}">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <Grid>
                        <Border Background="Bisque">
                            <TextBlock Text="{Binding Name"/>
                        </Border>
                        <ListView Name="SubItemsList" ItemsSource="{Binding Project}" ItemClick="SubItemClick">
                        <x:String>SubItem 1</x:String>
                        <x:String>SubItem 2</x:String>
                        <x:String>SubItem 3</x:String>
                        </ListView>
                    </Grid>
                </DataTemplate>
            </ListView.ItemTemplate>
        <x:String>Item 1</x:String>
        <x:String>Item 2</x:String>
        <x:String>Item 3</x:String>
        </ListView>
    </Grid>
</Page>

All I want is to catch the click of a subItem(ItemClick="SubItemClick">) in my CustomersViewModel. Is that possible? I know for the sub-items list items, the data is a Project which is just a data model, it does not contain any click handler. But, how can I catch the click in the view model and not in the code-behind?

Also I'm uploading a picture to visualise what I want:

enter image description here

mbob
  • 590
  • 1
  • 4
  • 22

2 Answers2

3

What you really need is a ClickCommand in your viewmodel. But since the ListView control doesn't expose a ItemClickCommand, one common way is to use a behavior to establish the connection between your ClickCommand and the ItemClick event.

This particular behavior you are looking for is called InvokeCommandAction, which can be found in this nuget package.

Basically the end result would look something like this -

<ListView Name="HeaderList" ItemsSource="{Binding Customers}">
    <Interactivity:Interaction.Behaviors>
        <Interactions:EventTriggerBehavior EventName="ItemClick" SourceObject="{Binding ElementName=HeaderList}">
            <Interactions:InvokeCommandAction Command="{Binding ClickCommand}"/>
        <Interactions:EventTriggerBehavior>
    <Interactivity:Interaction.Behaviors>
Justin XL
  • 38,763
  • 7
  • 88
  • 133
  • What I am saying is that I need the "ClickCommand" to exist in CustomersViewModel and for the second ListView, the ItemSource is bound to a Project not to a CustomersViewModel. So I need somehow to send the click event back to CustomersViewModel. – mbob Feb 06 '17 at 07:15
  • @mbob how about using MvvmLightas messenger pattern to share the clicked item across? Are your two view models bound to different pages? – Justin XL Feb 06 '17 at 07:30
  • Customers is a property of CustomersViewModel which is bound to the main listview (Item 1, Item 2, etc). Every Customer will contain a list of Projects which will be the ItemSource for the second list(SubItem 1, Subitem 2, etc). So "Project" is not a viewmodel anymore, it is only a data model. – mbob Feb 06 '17 at 07:36
  • 2
    OK, so you just need an `ElementName` binding to map to your `CustomersViewModel`'s command. Something like this: `ItemClick="{Binding DataContext.ClickCommand, ElementName=HeaderList}"`. – Justin XL Feb 06 '17 at 07:54
  • 1
    Also, another approach is to use `ListView`'s group header feature to display a grouped list rather than having nested `ListView`s. – Justin XL Feb 06 '17 at 07:57
  • this worked for me: ItemClick="{Binding DataContext.ClickCommand, ElementName=HeaderList}" – mbob Feb 06 '17 at 08:20
  • Have a look at [this](https://msdn.microsoft.com/en-us/windows/uwp/data-binding/data-binding-in-depth). – Justin XL Feb 06 '17 at 08:24
  • Hello @JustinXL, I have the same problem setup however using ElementName, my nested list view does not find the parentListview. How can I ensure that nested listview always finds container listview's name as elementName? – Skynet094 Jul 18 '18 at 23:52
0

As Justin XL said, the answer I was looking for is this: ItemClick="{Binding DataContext.ClickCommand, ElementName=HeaderList}"

mbob
  • 590
  • 1
  • 4
  • 22
  • Hi, can you explain where you made that change? Cause, I can not find ElementName of Parent ListView from Child ListView ..Please share if you have come across a solution for this problem. :) – Skynet094 Jul 06 '18 at 00:37