#c# #xamarin #xamarin.forms #mvvm #xamarin.android
Вопрос:
Итак, у меня есть приложение xamarin forms, которое в настоящее время реализовано только для Android. Я пытаюсь реализовать событие tap. При нажатии, хотя это никогда не попадает в команду в ViewModel. Я не уверен, что у меня что-то не так с моим кодом, или я просто неправильно его реализую.
Код модели просмотра:
private RelayCommand<object> _OnClickableLabel;
public RelayCommand<object> OnClickableLabel
{
get { return _OnClickableLabel ?? (_OnClickableLabel = new RelayCommand<object>((currentObject) => Test(currentObject))); }
}
private void Test(object currentObject)
{
Application.Current.MainPage.DisplayAlert("Alert", "were going down cap", "OK");
}
Страница Xaml:
<ListView Grid.Row="1" ItemsSource="{Binding Notifications}" RowHeight="100">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Vertical" BackgroundColor="{Binding BackgroundColor}">
<StackLayout.GestureRecognizers>
<TapGestureRecognizer Command="{Binding OnClickableLabel }" />
</StackLayout.GestureRecognizers>
<Label FontSize="Large" Text="{Binding Title}"></Label>
<Label FontSize="Small" Text="{Binding Text}"></Label>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Я протестировал его с помощью метода в cs-коде страницы, и это работает нормально, но его необходимо реализовать в ViewModel, потому что это влияет на эти данные.
Комментарии:
1. ваша команда находится на базовой виртуальной машине, но
BindingContext
каждая строка вListView
ней является отдельнымNotification
объектом, а не всей виртуальной машиной. Вы можете обойти это, используя относительную привязку2. Не знал об этом, довольно новичок в Xamarin. Я предполагаю, что использую версию RelativeSource типа AncestorType? Где мне выяснить, какой тип должен быть в AncestorType? Размещение модели представления там, похоже, не работает.
3. Другой обходной путь может заключаться в том, чтобы дать вашей странице имя , например
x:Name="this"
, затем указать источник в привязке, что-то вроде:Command="{Binding OnClickableLabel, Source={x:Reference this} }"
Ответ №1:
Из вашего описания следует, что вы хотите добавить распознаватель жестов касания в ListView и хотите передать данные текущей строки ListView в событие TapGestureRecognizer, я прав?
Если да, то, по мнению Джейсона, вам нужно взглянуть на Xamarin.Формирует относительные привязки во-первых,назовите ListView как listview1, затем посмотрите следующий код:
<ListView
x:Name="listview1"
Grid.Row="1"
ItemsSource="{Binding Notifications}"
RowHeight="100">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout BackgroundColor="{Binding BackgroundColor}" Orientation="Vertical">
<StackLayout.GestureRecognizers>
<TapGestureRecognizer Command="{Binding BindingContext.OnClickableLabel, Source={x:Reference listview1}}" CommandParameter="{Binding .}" />
</StackLayout.GestureRecognizers>
<Label FontSize="Large" Text="{Binding Title}" />
<Label FontSize="Small" Text="{Binding Text}" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
public partial class Page16 : ContentPage
{
public ObservableCollection<Notclass> Notifications { get; set; }
public ICommand OnClickableLabel { get; set; }
public Page16()
{
InitializeComponent();
Notifications = new ObservableCollection<Notclass>()
{
new Notclass(){Title="title 1",Text="notification 1"},
new Notclass(){Title="title 2",Text="notification 2"},
new Notclass(){Title="title 3",Text="notification 3"},
new Notclass(){Title="title 4",Text="notification 4"},
new Notclass(){Title="title 5",Text="notification 5"}
};
OnClickableLabel = new Command(n=> {
var vm = (Notclass)n;
Application.Current.MainPage.DisplayAlert("Alert",vm.Title , "OK");
});
this.BindingContext = this;
}
}
public class Notclass
{
public string Title { get; set; }
public string Text { get; set; }
public Color BackgroundColor { get; set; } = Color.White;
}