xamarin - How can I add command to control in datatemplate of collectionview - Stack Overflow

admin2025-05-02  1

I have a CollectionView which shows Thumbnail image in the first column and some data in the 2nd column.

I am trying to bind another command to the Thumbnail in the first column, so that when I click it a popup is opened.

Below is the xaml.

    <CollectionView x:Name="profilesCollectionView" ItemsSource="{Binding Profiles}" 
            VerticalOptions="FillAndExpand" SelectionMode="Single" 
            SelectionChangedCommand="{Binding ViewProfileCommand}"
            SelectedItem="{Binding SelectedProfile}"
            SelectionChangedCommandParameter="{Binding Path=SelectedItem, Source={x:Reference profilesCollectionView}}"
            >
        <CollectionView.ItemTemplate>
            <DataTemplate>
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="*"/>
                        <RowDefinition Height="1"/>
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="94"/>
                        <ColumnDefinition Width="*"/>
                    </Grid.ColumnDefinitions>
                    <!--<Frame HorizontalOptions="Center" IsClippedToBounds="True" CornerRadius="4" HasShadow="False" Grid.Row="0" 
                   Grid.Column="0" HeightRequest="72" WidthRequest="72" Padding="0">-->
                        <Image Grid.Column="0" Grid.Row="0" HorizontalOptions="Center" VerticalOptions="FillAndExpand" 
                       HeightRequest="72" WidthRequest="72" 
                       Aspect="Fill">
                            <Image.Source>
                                <UriImageSource Uri="{Binding ThumbNailUri}"/>
                            </Image.Source>
                        </Image>
                </Grid>
            </DataTemplate>
        </CollectionView.ItemTemplate>
    </CollectionView>

Below is the ViewModel code for SelectionChangedCommand

    [RelayCommand]
    public async Task ViewProfile(Object obj)
    {
    
        IsBusy = true;
        if (obj != null && obj is MiniProfile)
        {
            var item = (MiniProfile)obj;
    
            var sessionToken = await SecureStorage.GetAsync("Token");
            var targetProfileId = item.Id;
    
            //log the current user as visitor for the tapped profile
            await _serviceManager.CreateProfileVisitor(sessionToken, targetProfileId);
    
            var allRequests = await _serviceManager.GetAllRequests(sessionToken);
            var requestsSentToSelectedUser = allRequests.Where(ar => ar.ReceiverId == targetProfileId).ToList();
    
            var profileDetailsInput = ServiceHelper.InitialiseRequestsSent(requestsSentToSelectedUser);
    
            profileDetailsInput.LoggedInId = sessionToken;
            profileDetailsInput.TargetProfileId = targetProfileId;
    
            var profileDetailsParams = new Dictionary<string, object> { { "ProfileDetailsInput", profileDetailsInput } };
            IsBusy = false;
            await Shell.Current.GoToAsync("profiledetails", profileDetailsParams);
        }
    }

I have implemented this same functionality using Syncfusion DataGrid control where I get the column index that fired the event.

Is it possible to know which column or control fired the click event using CollectionView?

I have a CollectionView which shows Thumbnail image in the first column and some data in the 2nd column.

I am trying to bind another command to the Thumbnail in the first column, so that when I click it a popup is opened.

Below is the xaml.

    <CollectionView x:Name="profilesCollectionView" ItemsSource="{Binding Profiles}" 
            VerticalOptions="FillAndExpand" SelectionMode="Single" 
            SelectionChangedCommand="{Binding ViewProfileCommand}"
            SelectedItem="{Binding SelectedProfile}"
            SelectionChangedCommandParameter="{Binding Path=SelectedItem, Source={x:Reference profilesCollectionView}}"
            >
        <CollectionView.ItemTemplate>
            <DataTemplate>
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="*"/>
                        <RowDefinition Height="1"/>
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="94"/>
                        <ColumnDefinition Width="*"/>
                    </Grid.ColumnDefinitions>
                    <!--<Frame HorizontalOptions="Center" IsClippedToBounds="True" CornerRadius="4" HasShadow="False" Grid.Row="0" 
                   Grid.Column="0" HeightRequest="72" WidthRequest="72" Padding="0">-->
                        <Image Grid.Column="0" Grid.Row="0" HorizontalOptions="Center" VerticalOptions="FillAndExpand" 
                       HeightRequest="72" WidthRequest="72" 
                       Aspect="Fill">
                            <Image.Source>
                                <UriImageSource Uri="{Binding ThumbNailUri}"/>
                            </Image.Source>
                        </Image>
                </Grid>
            </DataTemplate>
        </CollectionView.ItemTemplate>
    </CollectionView>

Below is the ViewModel code for SelectionChangedCommand

    [RelayCommand]
    public async Task ViewProfile(Object obj)
    {
    
        IsBusy = true;
        if (obj != null && obj is MiniProfile)
        {
            var item = (MiniProfile)obj;
    
            var sessionToken = await SecureStorage.GetAsync("Token");
            var targetProfileId = item.Id;
    
            //log the current user as visitor for the tapped profile
            await _serviceManager.CreateProfileVisitor(sessionToken, targetProfileId);
    
            var allRequests = await _serviceManager.GetAllRequests(sessionToken);
            var requestsSentToSelectedUser = allRequests.Where(ar => ar.ReceiverId == targetProfileId).ToList();
    
            var profileDetailsInput = ServiceHelper.InitialiseRequestsSent(requestsSentToSelectedUser);
    
            profileDetailsInput.LoggedInId = sessionToken;
            profileDetailsInput.TargetProfileId = targetProfileId;
    
            var profileDetailsParams = new Dictionary<string, object> { { "ProfileDetailsInput", profileDetailsInput } };
            IsBusy = false;
            await Shell.Current.GoToAsync("profiledetails", profileDetailsParams);
        }
    }

I have implemented this same functionality using Syncfusion DataGrid control where I get the column index that fired the event.

Is it possible to know which column or control fired the click event using CollectionView?

Share Improve this question edited Jan 2 at 12:48 Rafael 2,0572 gold badges26 silver badges64 bronze badges asked Jan 2 at 3:05 shamsham 7779 silver badges29 bronze badges 2
  • Add a TapGestureRecognizer to the image – Jason Commented Jan 2 at 3:27
  • How do I pass command parameter to this tap command? – sham Commented Jan 2 at 12:50
Add a comment  | 

1 Answer 1

Reset to default 2

As @Jason suggested add a tap gesture to you Image. You need have a new command defined to handle Image tap. Also, you need to reference the command explicitly in order it to fire.

     <Image Grid.Column="0" Grid.Row="0" HorizontalOptions="Center" VerticalOptions="FillAndExpand" 
HeightRequest="72" WidthRequest="72" 
Aspect="Fill">
         <Image.Source>
             <UriImageSource Uri="{Binding ThumbNailUri}"/>
         </Image.Source>
         <Image.GestureRecognizers>
               <TapGestureRecognizer Command="{Binding Source={x:Reference list},Path=BindingContext.MyTappedCommand}" 
                          CommandParameter="{Binding .}"
                          NumberOfTapsRequired="1" />
         </Image.GestureRecognizers>
     </Image>

In viewmodel

 public ICommand MyTappedCommand => new Command((obj) =>
 {
     // when image is tapped
     if(obj is Profile tappedProfile)
     {
       //do stuff
     }
 });

Note: In this case the Item wont get selected if the user tap's on the image.

转载请注明原文地址:http://www.anycun.com/QandA/1746135641a92065.html