Hello,
Welcome to our Microsoft Q&A platform!
Firstly, I make a test in my side. I use listview and put two Buttons in the <ViewCell> like following xml. Button click event inside list view cell is works as well.
My xamarin.Forms version is 5.0.0.2012, you can create a new project, then copy my following code to it, If it works, If following code worked as normal, this issue is related to your custom row, please share this part of code, or share a demo directly(recommanded).
<ListView ItemsSource="{Binding Monkeys}" HasUnevenRows="True" ItemSelected="ListView_ItemSelected" SelectionMode="None">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout >
<Label
Text="{Binding Name}"
FontAttributes="Bold" />
<Label
Text="{Binding Location}"
FontAttributes="Italic"
VerticalOptions="End" />
<Button Text="Btn1" Clicked="Button_Clicked_1"/>
<Button Text="Btn2" Clicked="Button_Clicked_2"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Then here is my background code. I will pop up a DisplayAlert
when click a button to valiate the click event .
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
BindingContext = new MonkeysViewModel();
}
private void Button_Clicked(object sender, EventArgs e)
{
}
private void Button_Clicked_1(object sender, EventArgs e)
{
DisplayAlert("info1", "Button_Clicked_1","OK");
}
private void Button_Clicked_2(object sender, EventArgs e)
{
DisplayAlert("info2", "Button_Clicked_2", "OK");
}
private void ListView_ItemSelected(object sender, SelectedItemChangedEventArgs e)
{
DisplayAlert("ItemSelected", "ListView_ItemSelected", "OK");
}
}
Here is my viewModel.
public class MonkeysViewModel : INotifyPropertyChanged
{
readonly IList<Monkey> source;
Monkey selectedMonkey;
int selectionCount = 1;
public ObservableCollection<Monkey> Monkeys { get; private set; }
public IList<Monkey> EmptyMonkeys { get; private set; }
public Monkey SelectedMonkey
{
get
{
return selectedMonkey;
}
set
{
if (selectedMonkey != value)
{
selectedMonkey = value;
}
}
}
ObservableCollection<object> selectedMonkeys;
public ObservableCollection<object> SelectedMonkeys
{
get
{
return selectedMonkeys;
}
set
{
if (selectedMonkeys != value)
{
selectedMonkeys = value;
}
}
}
public string SelectedMonkeyMessage { get; private set; }
public ICommand DeleteCommand => new Command<Monkey>(RemoveMonkey);
// public ICommand FavoriteCommand => new Command<Monkey>(FavoriteMonkey);
public ICommand FilterCommand => new Command<string>(FilterItems);
public ICommand MonkeySelectionChangedCommand => new Command(MonkeySelectionChanged);
public MonkeysViewModel()
{
source = new List<Monkey>();
CreateMonkeyCollection();
selectedMonkey = Monkeys.Skip(3).FirstOrDefault();
MonkeySelectionChanged();
SelectedMonkeys = new ObservableCollection<object>()
{
Monkeys[1], Monkeys[3], Monkeys[4]
};
}
void CreateMonkeyCollection()
{
source.Add(new Monkey
{
Name = "Baboon",
Location = "Africa & Asia",
Details = "Baboons are African and Arabian Old World monkeys belonging to the genus Papio, part of the subfamily Cercopithecinae.",
ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/thumb/f/fc/Papio_anubis_%28Serengeti%2C_2009%29.jpg/200px-Papio_anubis_%28Serengeti%2C_2009%29.jpg"
});
Monkeys = new ObservableCollection<Monkey>(source);
}
void FilterItems(string filter)
{
var filteredItems = source.Where(monkey => monkey.Name.ToLower().Contains(filter.ToLower())).ToList();
foreach (var monkey in source)
{
if (!filteredItems.Contains(monkey))
{
Monkeys.Remove(monkey);
}
else
{
if (!Monkeys.Contains(monkey))
{
Monkeys.Add(monkey);
}
}
}
}
void MonkeySelectionChanged()
{
SelectedMonkeyMessage = $"Selection {selectionCount}: {SelectedMonkey.Name}";
OnPropertyChanged("SelectedMonkeyMessage");
selectionCount++;
}
void RemoveMonkey(Monkey monkey)
{
if (Monkeys.Contains(monkey))
{
Monkeys.Remove(monkey);
}
}
//void FavoriteMonkey(Monkey monkey)
//{
// monkey.IsFavorite = !monkey.IsFavorite;
//}
#region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}
public class Monkey
{
public string Name { get; set; }
public string Location { get; set; }
public string Details { get; set; }
public string ImageUrl { get; set; }
}
========================
Update==============================
I find the <RefreshView> canot not wrap the <Listview>
, And <ListView>
have IsPullToRefreshEnabled
, IsRefreshing
and RefreshCommand
function, you can move <RefreshView>
. using following code.
<StackLayout>
<Label Text="Test" />
<!--<RefreshView Grid.Row="0" Grid.RowSpan="1" x:Name="InvitationRefreshView" Refreshing="Invitation_Refreshing">-->
<ListView x:Name="InviteListView" SeparatorColor="LightGray" BackgroundColor="White" RowHeight="80" Margin="10,0,15,0" IsPullToRefreshEnabled="True" IsRefreshing="{Binding IsRefreshing}" RefreshCommand="{Binding RefreshCommand}" SelectionMode="None">
<ListView.ItemsSource>
<x:Array Type="{x:Type x:String}">
<x:String>mono</x:String>
<x:String>monodroid</x:String>
<x:String>monotouch</x:String>
<x:String>monorail</x:String>
<x:String>monodevelop</x:String>
<x:String>monotone</x:String>
<x:String>monopoly</x:String>
<x:String>monomodal</x:String>
<x:String>mononucleosis</x:String>
</x:Array>
</ListView.ItemsSource>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="70" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="140" />
</Grid.ColumnDefinitions>
<StackLayout Orientation="Horizontal" VerticalOptions="Center" WidthRequest="55" MinimumWidthRequest="55" HeightRequest="55" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="1">
<Frame CornerRadius="3" IsClippedToBounds="True" Padding="0" HasShadow="False">
<StackLayout WidthRequest="55" MinimumWidthRequest="55" HeightRequest="55" Margin="0" VerticalOptions="Center" Padding="0">
<Image IsVisible="true" Source="LargeAvatarDefault.png" VerticalOptions="CenterAndExpand" WidthRequest="55" MinimumWidthRequest="55" HeightRequest="50" Aspect="AspectFill" />
<Label BackgroundColor="Green" WidthRequest="55" MinimumWidthRequest="55" HeightRequest="5" Margin="0,-6,0,0"/>
</StackLayout>
</Frame>
</StackLayout>
<Label Text="{Binding .}" Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="1" VerticalOptions="CenterAndExpand" VerticalTextAlignment="Center" HorizontalOptions="StartAndExpand" HorizontalTextAlignment="Start"/>
<StackLayout Orientation="Horizontal" Grid.Row="0" Grid.Column="2" Grid.ColumnSpan="1" VerticalOptions="CenterAndExpand" HorizontalOptions="EndAndExpand" Spacing="10">
<Button Text="Accept" TextColor="White" BackgroundColor="Orange" Clicked="Accept_Clicked" HeightRequest="40" FontSize="12" Padding="0" WidthRequest="60"/>
<Button Text="Decline" TextColor="White" BackgroundColor="#355466" Clicked="Decline_Clicked" HeightRequest="40" WidthRequest="60" FontSize="12" Padding="0" />
</StackLayout>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<!--</RefreshView>-->
</StackLayout>
Here is layout backgrounc code.
public partial class MainPage : ContentPage
{
private bool _isRefreshing = false;
public bool IsRefreshing
{
get { return _isRefreshing; }
set
{
_isRefreshing = value;
OnPropertyChanged(nameof(IsRefreshing));
}
}
public ICommand RefreshCommand
{
get
{
return new Command(async () =>
{
IsRefreshing = true;
// await RefreshData();
IsRefreshing = false;
});
}
}
public MainPage()
{
InitializeComponent();
BindingContext =this;
}
private async void Accept_Clicked(object sender, EventArgs e)
{
await Task.Delay(1000);
await DisplayAlert("Alert", "Acceopt Clicked", "OK");
}
private async void Decline_Clicked(object sender, EventArgs e)
{
await Task.Delay(1000);
await DisplayAlert("Alert", "Declne Clicked", "OK");
}
}
Best Regards,
Leon Lu
If the response is helpful, please click "Accept Answer" and upvote it.
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.