如何在 MVVM 模式中处理嵌套 ListView 的 ItemClick?
How to handle ItemClick For Nested ListView In MVVM Pattern?
Xaml代码:
<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>
视图模型代码:
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" });
}
}
}
这是演示我的问题的演示代码。
当我单击 SubItemsList 上的任何项目时,我希望将事件绑定到视图模型中的命令,我该如何实现?
感谢阅读。
我已经查看了来自 Whosebug 的两个资源,但其中 none 有任何可用的资源。
仅供参考,我是 UWP 的新手,对 MVVM 更是如此。
对于MVVM 模式中嵌套的ListView
ItemClick
,您可以使用Xaml Behaviors SDK 添加ItemClick
事件,如下所示。
<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>
并且您需要添加 SelectedItem="{Binding SelectItme,Mode=TwoWay}"
用于标识您选择的项目。
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;
}
}
Xaml代码:
<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>
视图模型代码:
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" });
}
}
}
这是演示我的问题的演示代码。
当我单击 SubItemsList 上的任何项目时,我希望将事件绑定到视图模型中的命令,我该如何实现?
感谢阅读。
我已经查看了来自 Whosebug 的两个资源,但其中 none 有任何可用的资源。
仅供参考,我是 UWP 的新手,对 MVVM 更是如此。
对于MVVM 模式中嵌套的ListView
ItemClick
,您可以使用Xaml Behaviors SDK 添加ItemClick
事件,如下所示。
<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>
并且您需要添加 SelectedItem="{Binding SelectItme,Mode=TwoWay}"
用于标识您选择的项目。
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;
}
}