Привязка к элементу ListView элемента ListView из View Model
Я пытаюсь связать событие с ListView на моей странице меню, используя свойство itemtapped. В настоящее время я использую среду MVVM (Xamarin form labs) в своем приложении. То, что я пытаюсь выполнить, - это когда пользователь набирает пункт меню, приложение переходит к правильному виду.
Вот код xaml:
<ListView x:Name="list"
ItemsSource="{Binding MenuItems}"
SelectedItem="{Binding SelectedItem}"
ItemTapped= SET-BINDING-HERE >
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.View>
//setup template here
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Я хочу привязать событие itemtapped к этой функции:
public void NavigateTo(object sender, ItemTappedEventArgs args)
{
var test = args.Item as MenuModel;
cPageTypes.GetByKey(test.CommandParameter)
.SwitchRootPage(AIMCore.ViewModels.ElliottBaseViewModel.MasterPage);
list.SelectedItem = null;
AIMCore.ViewModels.BaseViewModel.MasterPage.IsPresented = false;
}
В настоящее время я могу заставить это работать, если добавить функцию в код представления позади, а затем установить ItemTapped = 'NavigatTo', но это кажется неправильным, поскольку оно побеждает концепцию MVVM. То, что я действительно хочу сделать, это привязать событие к этой же функциональности в моей ViewModel примерно так:
<ListView x:Name="list"
ItemsSource="{Binding MenuItems}"
SelectedItem="{Binding SelectedItem}"
ItemTapped= "{Binding NavigateTo}" > // this binding is to the ViewModel
Однако это не работает, или я не делаю это правильно. Когда я пытаюсь реализовать его таким образом, код генерирует и создает ошибку.
Ошибка:
Xamarin.Forms.Xaml.XamlParseException: Нет Свойство name ItemTapped найдено на Xamarin.Forms.Xaml.BaseValueNode.SetPropertyValue
Ответы
Ответ 1
Я следил за той же архитектурой и делал это через создание настраиваемого элемента управления списком и создал 1 свойство bindable с командой, которую я переопределил в моей модели просмотра, используя приведенный ниже код:
Пользовательский элемент управления [.cs] в моем PCL
using System;
using System.Windows.Input;
using Xamarin.Forms;
namespace YourNS {
public class ListView : Xamarin.Forms.ListView {
public static BindableProperty ItemClickCommandProperty = BindableProperty.Create<ListView, ICommand>(x => x.ItemClickCommand, null);
public ListView() {
this.ItemTapped += this.OnItemTapped;
}
public ICommand ItemClickCommand {
get { return (ICommand)this.GetValue(ItemClickCommandProperty); }
set { this.SetValue(ItemClickCommandProperty, value); }
}
private void OnItemTapped(object sender, ItemTappedEventArgs e) {
if (e.Item != null && this.ItemClickCommand != null && this.ItemClickCommand.CanExecute(e)) {
this.ItemClickCommand.Execute(e.Item);
this.SelectedItem = null;
}
}
}
}
Моя страница XAML
<ContentPage ...
xmlns:local="clr-namespace:Samples.Views;assembly=Your Assebly Name">
<local:ListView ItemClickCommand="{Binding Select}"
ItemsSource="{Binding List}">
И в моей модели просмотра [В этом примере я только открыл окно действий диалогового окна
private Command<Signature> selectCmd;
public Command<Signature> Select {
get {
this.selectCmd = this.selectCmd ?? new Command<Signature>(s =>
this.dialogs.ActionSheet(new ActionSheetConfig()
.Add("View", () => {
if (!this.fileViewer.Open(s.FilePath))
this.dialogs.Alert(String.Format("Could not open file {0}", s.FileName));
})
.Add("Cancel")
)
);
return this.selectCmd;
}
}
Ответ 2
В качестве альтернативы вы можете использовать Attached Behavior
public static class ListViewAttachedBehavior
{
public static readonly BindableProperty CommandProperty =
BindableProperty.CreateAttached (
"Command",
typeof(ICommand),
typeof(ListViewAttachedBehavior),
null,
propertyChanged:OnCommandChanged);
static void OnCommandChanged (BindableObject view, object oldValue, object newValue)
{
var entry = view as ListView;
if (entry == null)
return;
entry.ItemTapped += (sender, e) =>
{
var command = (newValue as ICommand);
if(command == null)
return;
if(command.CanExecute(e.Item))
{
command.Execute(e.Item);
}
};
}
}
Затем вызовите его в списке ListView
<ListView
RowHeight="70"
x:Name="AcquaintanceListView"
b:ListViewAttachedBehavior.Command="{Binding ItemSelectedCommand}"
ItemsSource="{Binding Acquaintances}">