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?
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.