Reputation: 131
I am using a ListView to display the titles of 'assignments' that I get from an API. Once I click on an assignment, I want to go to the details page of this assignment. Here I want to show the description and id of the selected assignment. I have this all almost figured out, but I am stuck.
My XAML page looks like this:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="App.Views.AssignmentListPage"
Title="Opdrachten">
<ListView x:Name="AssignmentsListView" Margin="20">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Padding="20,0,0,0" HorizontalOptions="StartAndExpand" Orientation="Horizontal">
<Label Text="{Binding Title}" VerticalTextAlignment="Center">
<Label.GestureRecognizers>
<TapGestureRecognizer Tapped="OnLabelClicked" CommandParameter="{Binding .}"/>
</Label.GestureRecognizers>
</Label>
<!--<Label Text="{Binding Title}" VerticalTextAlignment="Center">
<Label.GestureRecognizers>
<TapGestureRecognizer Command="viewDetails" CommandParameter="{Binding .}"/>
</Label.GestureRecognizers>
</Label>-->
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
My code-behind looks like this:"
public partial class AssignmentListPage : ContentPage
{
public AssignmentListPage ()
{
InitializeComponent ();
}
protected override async void OnAppearing()
{
base.OnAppearing();
AssignmentsListView.ItemsSource = await App.AssignmentManager.GetAssignmentsAsync();
}
async void OnLabelClicked(object s, EventArgs e)
{
var a = e.ToString();
var assignment = new Assignment
{
Id = "1234",
Title = "Cross-Platform Application",
Description = "What a beautiful description"
};
var assignmentDetailsPage = new AssignmentDetailsPage
{
BindingContext = assignment
};
await Navigation.PushAsync(assignmentDetailsPage);
}
}
As you can see, I've hard-coded the id, title, and description in the OnLabelClicked
function. I want to use e.Parameter
to get these data, but that is not something I can select. I can only choose from ToString
, Equals
, getType
. But when I run the application and inspect e
, it does contains 'Parameter`. See picture.
I've tried using Command
instead of Tapped
in the XAML file, but without success. I couldn't find out how to do that.
I am new to all of this and I've been working all day on this issue. I got a little bit of tunnel vision. I hope you guys can point me in the right direction.
Upvotes: 0
Views: 1600
Reputation: 2901
You are mixing two different user interaction patterns that aren't intended to be mixed. You can go the route @Jason suggests and use the event pattern, which would be equivalent to the event-driven paradigms used in lots of UI frameworks, including WinForms. It is fully supported in XAML-based frameworks (WPF, Xamarin, etc.) as well, but it's worth understanding the command pattern as well.
The command pattern is build for a more declarative usage model and is a part of the MVVM model of application development. The idea is that you use data binding to create looser connections between front-end views and the objects (in this case called a view-model) that back them.
Whereas in event patterns you would wire up event handlers which get called via .NET delegates, commands are classes deriving from ICommand
, and objects of these types are used both the execute the desired logic as well as to do things like indicate state (whether the command can be invoked at the current time or not).
In this case, you'd bind an ICommand
object (usually a bindable property of your view-model) to the Command
property of your TapGestureRecognizer
and the value you want to pass to the CommandParameter
property. Upon invocation, the CommandParameter
will be passed to the Execute
method of the Command
object.
For more complete code samples, refer to the linked articles (the first one, on commanding in Xamarin, in particular).
However, you can indeed go back to the tried-and-true event-based model of interaction if you want. There are pros and cons to each.
Upvotes: 0
Reputation: 89082
ListView
has built-in ItemTapped
and ItemSelected
events that will do what you want
<ListView x:Name="AssignmentsListView" Margin="20" ItemSelected="OnItemSelect">
public void OnItemSelect(sender s, SelectedItemChangedEventArgs a)
{
// a.SelectedItem will be the selected Item, you need to cast it
var item = (MyClass)a.SelectedItem;
...
}
Upvotes: 2