Forum Xamarin.Forms

How to send arguments from ViewCell.Tapped event to next page

I'm working on a simple application to get to know some of the Xamarin basics. Now I'm stuck when switching pages, as I want to send a variable ID to the next page, to enable that page to retrieve the right data.

I've added the tapped property to the ViewCell, and refer to the CategoryClicked class. Then I am looking to get the ID of the selected ViewCell. But I cannot find it in the EventArgs.

What would be the right way to do this?

Currently I have the following code (i simplified it a bit)

CardCategories.xaml

<ContentPage.Content>
        <StackLayout>
            <ListView x:Name="CardCategoriesListView" RowHeight="100">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <ViewCell Tapped="CategoryClicked">
                            <StackLayout BackgroundColor="{Binding Color}" Orientation="Horizontal">
                                <Label
                                    Margin="20"
                                    FontSize="30"
                                    HorizontalOptions="Start"
                                    Text="{Binding Icon}"
                                    TextColor="White"
                                    VerticalOptions="CenterAndExpand">
                                    <Label.FontFamily>
                                        <OnPlatform x:TypeArguments="x:String">
                                            <OnPlatform.iOS>MaterialIcons-Regular</OnPlatform.iOS>
                                            <OnPlatform.Android>Fonts/MaterialIcons-Regular.ttf#MaterialIcons-Regular</OnPlatform.Android>
                                            <OnPlatform.WinPhone>Assets/Fonts/MaterialIcons-Regular.ttf#MaterialIcons-Regular</OnPlatform.WinPhone>
                                        </OnPlatform>
                                    </Label.FontFamily>
                                </Label>
                </StackLayout>
                        </ViewCell>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

CardCategories.xaml.cs

namespace UXCards
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class CardCategories : ContentPage
    {
        public CardCategories()
        {
            InitializeComponent();
            CardCategoriesListView.ItemsSource = ViewModel.UXCardsViewModel.uxCardCategories;
        }

        async void CategoryClicked(object sender, SelectedItemChangedEventArgs e)
        {

            var cardSubCategory = new CardSubCategories();
            cardSubCategory.CategorySelected = 0; // Here I want to send the ID to the next page

            await Navigation.PushAsync(cardSubCategory);
        }
    }
}

Best Answer

  • MatthijsMali.5488MatthijsMali.5488 USMember ✭✭
    edited July 2017 Accepted Answer

    I found a working solution. The things I did to get it to work were the following

    • Add ItemTapped property to the listview
    • Add ItemTappedEventArgs to the Clickhandler
    • Convert the received argument to the right model
    • Create the navigation.push towards the new page
    • Added the cardCategory to the new page as an itemssource

    My code is now as follows:

    CardCategories.xaml (i've ommitted some code)

    <StackLayout>
                <ListView
                    x:Name="CardCategoriesListView"
                    ItemTapped="CategoryClicked"
                    RowHeight="100">
                    <ListView.ItemTemplate>
                        <DataTemplate>
                            <ViewCell>
                                <StackLayout BackgroundColor="{Binding Color}" Orientation="Horizontal">
                                    <Label
                                        Margin="20"
                                        FontSize="30"
                                        HorizontalOptions="Start"
                                        Text="{Binding Icon}"
                                        TextColor="White"
                                        VerticalOptions="CenterAndExpand">
                                        <Label.FontFamily>
                                            <OnPlatform x:TypeArguments="x:String">
                                                <OnPlatform.iOS>MaterialIcons-Regular</OnPlatform.iOS>
                                                <OnPlatform.Android>Fonts/MaterialIcons-Regular.ttf#MaterialIcons-Regular</OnPlatform.Android>
                                                <OnPlatform.WinPhone>Assets/Fonts/MaterialIcons-Regular.ttf#MaterialIcons-Regular</OnPlatform.WinPhone>
                                            </OnPlatform>
                                        </Label.FontFamily>
                                    </Label>
                                  </StackLayout>
                            </ViewCell>
                        </DataTemplate>
                    </ListView.ItemTemplate>
                </ListView>
            </StackLayout>
    

    CardCategories.xaml.cs

        [XamlCompilation(XamlCompilationOptions.Compile)]
        public partial class CardCategories : ContentPage
        {
            public CardCategories()
            {
                InitializeComponent();
                CardCategoriesListView.ItemsSource = ViewModel.UXCardsViewModel.uxCardCategories;
            }
    
            public async void CategoryClicked(object sender, ItemTappedEventArgs e)
            {
                Models.UXCardCategory cardCategory = (Models.UXCardCategory)e.Item;
                await Navigation.PushAsync(new CardSubCategories(cardCategory));
            }
        }
    

    CardSubCategories.xaml.cs

    [XamlCompilation(XamlCompilationOptions.Compile)]
        public partial class CardSubCategories : ContentPage
        {
            public object cardCategory { get; set; }
    
            public CardSubCategories(Models.UXCardCategory cardCategory)
            {
                InitializeComponent();
                CardSubCategoriesListView.ItemsSource = ViewModel.UXCardsViewModel.uxCardCategories.Find(x => x.Id == cardCategory.Id).UXCardSubCategories;
            }
        }
    

Answers

  • MatthijsMali.5488MatthijsMali.5488 USMember ✭✭

    Thanks. That got me a bit further.

    I've added the ItemTapped="CategoryClicked" to the ListView element. Then after the event has been fired, the ItemTappedEventArgs contains the object that was tapped. But now, when I want to pass that on to the next activity it Visual Studio complains that the cardCategory is an Object, but when I want to use it as ItemsSource, it should be a List.

    Is that correct behavior? Or am I missing something?

    CardCategories.xaml.cs contains this

    public async void CategoryClicked(object sender, ItemTappedEventArgs e)
            {
                Models.UXCardCategory cardCategory = (Models.UXCardCategory)e.Item;
    
                await Navigation.PushAsync(new CardSubCategories(cardCategory));
            }
    

    CardSubCategories.xaml.cs contains this:

    public partial class CardSubCategories : ContentPage
        {
            public object cardCategory { get; set; }
    
            public CardSubCategories(Models.UXCardCategory cardCategory)
            {
                InitializeComponent();
    
                CardSubCategoriesListView.ItemsSource = cardCategory;
            }
        }
    
  • MatthijsMali.5488MatthijsMali.5488 USMember ✭✭
    edited July 2017 Accepted Answer

    I found a working solution. The things I did to get it to work were the following

    • Add ItemTapped property to the listview
    • Add ItemTappedEventArgs to the Clickhandler
    • Convert the received argument to the right model
    • Create the navigation.push towards the new page
    • Added the cardCategory to the new page as an itemssource

    My code is now as follows:

    CardCategories.xaml (i've ommitted some code)

    <StackLayout>
                <ListView
                    x:Name="CardCategoriesListView"
                    ItemTapped="CategoryClicked"
                    RowHeight="100">
                    <ListView.ItemTemplate>
                        <DataTemplate>
                            <ViewCell>
                                <StackLayout BackgroundColor="{Binding Color}" Orientation="Horizontal">
                                    <Label
                                        Margin="20"
                                        FontSize="30"
                                        HorizontalOptions="Start"
                                        Text="{Binding Icon}"
                                        TextColor="White"
                                        VerticalOptions="CenterAndExpand">
                                        <Label.FontFamily>
                                            <OnPlatform x:TypeArguments="x:String">
                                                <OnPlatform.iOS>MaterialIcons-Regular</OnPlatform.iOS>
                                                <OnPlatform.Android>Fonts/MaterialIcons-Regular.ttf#MaterialIcons-Regular</OnPlatform.Android>
                                                <OnPlatform.WinPhone>Assets/Fonts/MaterialIcons-Regular.ttf#MaterialIcons-Regular</OnPlatform.WinPhone>
                                            </OnPlatform>
                                        </Label.FontFamily>
                                    </Label>
                                  </StackLayout>
                            </ViewCell>
                        </DataTemplate>
                    </ListView.ItemTemplate>
                </ListView>
            </StackLayout>
    

    CardCategories.xaml.cs

        [XamlCompilation(XamlCompilationOptions.Compile)]
        public partial class CardCategories : ContentPage
        {
            public CardCategories()
            {
                InitializeComponent();
                CardCategoriesListView.ItemsSource = ViewModel.UXCardsViewModel.uxCardCategories;
            }
    
            public async void CategoryClicked(object sender, ItemTappedEventArgs e)
            {
                Models.UXCardCategory cardCategory = (Models.UXCardCategory)e.Item;
                await Navigation.PushAsync(new CardSubCategories(cardCategory));
            }
        }
    

    CardSubCategories.xaml.cs

    [XamlCompilation(XamlCompilationOptions.Compile)]
        public partial class CardSubCategories : ContentPage
        {
            public object cardCategory { get; set; }
    
            public CardSubCategories(Models.UXCardCategory cardCategory)
            {
                InitializeComponent();
                CardSubCategoriesListView.ItemsSource = ViewModel.UXCardsViewModel.uxCardCategories.Find(x => x.Id == cardCategory.Id).UXCardSubCategories;
            }
        }
    
Sign In or Register to comment.