问题
Xaml code:
<Page
x:Class="DemoTestApp.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:DemoTestApp"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
xmlns:vm="using:ViewModels"
>
<Page.DataContext>
<vm:TestViewModel/>
</Page.DataContext>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<ListView Name="HeaderList" ItemsSource="{Binding Items}">
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Border Background="Bisque">
<TextBlock Text="{Binding Name}"/>
</Border>
<ListView Name="SubItemsList">
<x:String>SubItem 1</x:String>
<x:String>SubItem 2</x:String>
<x:String>SubItem 3</x:String>
</ListView>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</Page>
ViewModel Code:
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ViewModels
{
class TestViewModel
{
public class Item
{
public string Test { get; set; }
}
public ObservableCollection<Item> Items { get; set; }
public TestViewModel()
{
Items = new ObservableCollection<Item>();
Items.Add(new Item { Test = "Item 1" });
Items.Add(new Item { Test = "Item 2" });
Items.Add(new Item { Test = "Item 3" });
Items.Add(new Item { Test = "Item 4" });
Items.Add(new Item { Test = "Item 5" });
Items.Add(new Item { Test = "Item 7" });
Items.Add(new Item { Test = "Item 8" });
Items.Add(new Item { Test = "Item 9" });
Items.Add(new Item { Test = "Item 10" });
Items.Add(new Item { Test = "Item 11" });
}
}
}
This is a demo code to demonstrate my problem.
When I click on any item on the SubItemsList, I would like the event to be binded to a Command in the view model, how can I accomplish this?
Thanks for reading.
I have already looked at the two resources from stackoverflow, but none of them had anything that worked.
Just for the information, I am new to UWP and more of so to MVVM.
回答1:
For nested ListView
ItemClick
in MVVM pattern, you could use Xaml Behaviors SDK to add ItemClick
event just like the following.
<ListView Name="HeaderList" ItemsSource="{Binding Items}" >
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Border Background="Bisque">
<TextBlock Text="{Binding Test}"/>
</Border>
<ListView Name="SubItemsList" ItemsSource="{Binding SubItems}"
IsItemClickEnabled="True"
SelectedItem="{Binding SelectItme,Mode=TwoWay}" >
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding }"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
<i:Interaction.Behaviors >
<ic:EventTriggerBehavior EventName="ItemClick">
<ic:InvokeCommandAction Command="{Binding ItemCommand}"
CommandParameter="{Binding}" />
</ic:EventTriggerBehavior>
</i:Interaction.Behaviors>
</ListView>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
And you need to add SelectedItem="{Binding SelectItme,Mode=TwoWay}"
that use to identify which item you have selected.
ViewModel
class TestViewModel
{
public class Item : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
public string Test { get; set; }
public ObservableCollection<string> SubItems { get; set; }
private string _selectItme;
public string SelectItme
{
get
{
return _selectItme;
}
set
{
_selectItme = value;
OnPropertyChanged();
}
}
public Item()
{
SubItems = new ObservableCollection<string>() { "zhuzhu", "heheh", "liuliu", "momo" };
}
public ICommand ItemCommand
{
get
{
return new CommadEventHandler<object>((item) => ItemClick(item));
}
}
private void ItemClick(object item)
{
System.Diagnostics.Debug.WriteLine("--------------------");
}
}
public ObservableCollection<Item> Items { get; set; }
public TestViewModel()
{
Items = new ObservableCollection<Item>();
Items.Add(new Item { Test = "Item 1" });
Items.Add(new Item { Test = "Item 2" });
Items.Add(new Item { Test = "Item 3" });
Items.Add(new Item { Test = "Item 4" });
Items.Add(new Item { Test = "Item 5" });
Items.Add(new Item { Test = "Item 7" });
Items.Add(new Item { Test = "Item 8" });
Items.Add(new Item { Test = "Item 9" });
Items.Add(new Item { Test = "Item 10" });
Items.Add(new Item { Test = "Item 11" });
}
}
class CommadEventHandler<T> : ICommand
{
public event EventHandler CanExecuteChanged;
public Action<T> action;
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(object parameter)
{
this.action((T)parameter);
}
public CommadEventHandler(Action<T> action)
{
this.action = action;
}
}
来源:https://stackoverflow.com/questions/51428298/how-to-handle-itemclick-for-nested-listview-in-mvvm-pattern