Код 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, я хочу, чтобы событие было привязано к команде в модели представления, как я могу это сделать?
Спасибо за прочтение.
Я уже просмотрел два ресурса из stackoverflow, но ни один из них не работал.
Просто для информации, я новичок в UWP и, в большей степени, в MVVM.





Для вложенного ListViewItemClick в шаблоне MVVM вы можете использовать Xaml-поведения 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;
}
}
Что, если я не хочу хранить обработчик внутри Item, а не хочу поместить его в ViewModel? Это возможно? В моем проекте я делал именно то, что вы там показали: D Но в моем проекте элемент является частью модели ... поэтому мне было странно помещать обработчик событий (команду) внутри модели ... пожалуйста, скажите мне, если вы понимаете, о чем я говорю. Еще раз спасибо. :)
Да, я знаю ваши средства, но DataContext в subListView - это Item, а не TestViewModel, поэтому лучше делать команду в классе Item.
Почему «лучше»? Вы имеете в виду, что так проще / удобнее? : D Мы стараемся быть пуристами MVVM. Не уверен, что это ЧИСТЫЙ способ.
Если вам нужна команда bind в TestViewModel, вы можете попробовать использовать x:Bind, для получения дополнительной информации вы можете обратиться к это.
Что делать, если я не хочу использовать x: Bind? Причина x: Bind требует, чтобы я использовал DataType, что странно, я не могу использовать DataType, если помещаю свой шаблон данных в App.xaml: 3
Для Nested ListView я думаю, что команда make в Item - хороший способ реализовать эту функцию.
Пожалуйста, и это образец кода, на который вы могли бы сослаться.