如何在ListView(Xamarin)中处理特定控件的事件
我有一个带有ViewCell的Listview,在这个ViewCell中有3个图像和3个标签。为了处理点击事件,我为每个控件编写了一个手势识别器如何在ListView(Xamarin)中处理特定控件的事件,listview,xamarin.forms,Listview,Xamarin.forms,我有一个带有ViewCell的Listview,在这个ViewCell中有3个图像和3个标签。为了处理点击事件,我为每个控件编写了一个手势识别器 <ListView HasUnevenRows="True" SeparatorColor="White" ItemsSource="{Binding List}" SelectedItem="{Binding SelectedItem, Mode=TwoWay}"
<ListView HasUnevenRows="True"
SeparatorColor="White"
ItemsSource="{Binding List}"
SelectedItem="{Binding SelectedItem, Mode=TwoWay}"
ItemSelected="Handle_ItemSelected"
ItemTapped="ListView_ItemTapped">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Spacing="0">
<StackLayout Orientation="Horizontal" Padding="16,8,16,4">
<Image Source="{Binding IconImageSource}" HeightRequest="36" WidthRequest="36"/>
<StackLayout HorizontalOptions="StartAndExpand" Padding="8,0,0,0" Spacing="0">
<Label Text="{Binding LocalizedText}" TextColor="White"/>
<Label Text="{Binding Value}" TextColor="Gray" FontSize="Small"/>
</StackLayout>
</StackLayout>
<BoxView Color="WhiteSmoke" HeightRequest="1" HorizontalOptions="FillAndExpand" Opacity="0,5" />
<RelativeLayout Padding="0,4,0,4" >
<Image Source="ic_ecu_eye"
RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=0.25}"
RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=0, Constant=4}"
/>
<Label Text="{Binding ViewedCount}"
RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=0.25, Constant=20}" />
<Image Source="ic_ecu_favorite"
RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=0.5}"
RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=0, Constant=4}"/>
<Label Text="{Binding FavoriteCount}"
RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=0.5, Constant=20}" />
<Image Source="ic_ecu_comment"
RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=0.75}"
RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=0, Constant=4}">
<Image.GestureRecognizers>
<TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped" NumberOfTapsRequired="1"/>
</Image.GestureRecognizers>
</Image>
<Label Text="{Binding CommentsCount}"
RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=0.75, Constant=20}">
<Label.GestureRecognizers>
<TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped" NumberOfTapsRequired="1"/>
</Label.GestureRecognizers>
</Label>
</RelativeLayout>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
ListView_ItemTapped用于处理ListView tap事件
async private void ListView_ItemTapped(object sender, ItemTappedEventArgs e)
{ // easily get the tapped item via e.Item }
与listview tapped事件不同,TapGestureRecognitor_tapped无法轻松获取我需要处理某些逻辑的tapped项。
这就是我的问题,如果我在GestureRecognitor事件方法中点击Listview中的控件,我如何获得点击的项
async private void TapGestureRecognizer_Tapped(object sender, System.EventArgs e)
{
// TODO:
}
虽然您可以使用事件执行此操作,但我认为最好使用
TapGestureRecognizer
中的Command
属性执行此操作。我已经为您创建了一个示例项目来演示这一点。你可以找到它
放下属性,开始使用命令,如下所示
<Label.GestureRecognizers>
<TapGestureRecognizer Command="{Binding Path=BindingContext.TapCommand, Source={x:Reference Name=ThaPage}" CommandParameter="{Binding .}" />
</Label.GestureRecognizers>
在尖括号之间,可以指定所需的对象类型。你可以省去它。然后只传递一个对象
,您需要执行强制转换
然后在处理命令的方法中
您将可以使用点击的对象。我的例子中的对象是Foo
,仅此示例。虽然您可以使用事件执行此操作,但我认为最好使用TapGestureRecognizer
中的命令
属性执行此操作。我已经为您创建了一个示例项目来演示这一点。你可以找到它
放下属性,开始使用命令,如下所示
<Label.GestureRecognizers>
<TapGestureRecognizer Command="{Binding Path=BindingContext.TapCommand, Source={x:Reference Name=ThaPage}" CommandParameter="{Binding .}" />
</Label.GestureRecognizers>
在尖括号之间,可以指定所需的对象类型。你可以省去它。然后只传递一个对象
,您需要执行强制转换
然后在处理命令的方法中
您将可以使用点击的对象。我的例子中的对象是Foo
,就本例而言。Gerald answer就是答案
顺便说一句,我想你可以试试
async private void TapGestureRecognizer_Tapped(object sender, System.EventArgs e)
{
// want to get listview item
await Application.Current.MainPage.DisplayAlert("Article", ((YourModel)this.BindingContext).YourField, "Ok");
}
我尝试过用代码创建ViewCell,它可以工作。我不知道您是否在使用XAML创建ViewCell时遇到问题
这是我的ViewCell的完整代码
class ListViewTemplateGrid : ViewCell
{
public ListViewTemplateGrid(){
TapGestureRecognizer tgr = new TapGestureRecognizer();
tgr.Tapped += async (object sender, EventArgs e) => {
try {
await Application.Current.MainPage.DisplayAlert("Article", ((ListViewModel)this.BindingContext).Description, "Ok");
}
catch(Exception ex){
await Application.Current.MainPage.DisplayAlert("Error", ex.Message, "Ok");
}
};
Label labelDescription = new Label() {VerticalOptions = LayoutOptions.Center};
labelDescription.SetBinding(Label.TextProperty, "Description");
labelDescription.GestureRecognizers.Add(tgr);
Label labelQty = new Label() { VerticalOptions = LayoutOptions.Center, HorizontalOptions = LayoutOptions.Center };
labelQty.SetBinding(Label.TextProperty, "Qty");
Label labelOrdered = new Label() { VerticalOptions = LayoutOptions.Center, HorizontalOptions = LayoutOptions.Center };
labelOrdered.SetBinding(Label.TextProperty, "Ordered");
// Add controls to the grid
Grid grid = CreateGrid();
grid.Children.Add(labelDescription, 0,1,0,1);
grid.Children.Add(SeparatorV(), 1, 2, 0, 1);
grid.Children.Add(labelQty, 2, 3, 0, 1);
grid.Children.Add(SeparatorV(), 3, 4, 0, 1);
grid.Children.Add(labelOrdered, 4, 5, 0, 1);
grid.Children.Add(SeparatorH(), 0, 5, 1, 2);
this.View = grid;
}
}
杰拉尔德的答案就是答案
顺便说一句,我想你可以试试
async private void TapGestureRecognizer_Tapped(object sender, System.EventArgs e)
{
// want to get listview item
await Application.Current.MainPage.DisplayAlert("Article", ((YourModel)this.BindingContext).YourField, "Ok");
}
我尝试过用代码创建ViewCell,它可以工作。我不知道您是否在使用XAML创建ViewCell时遇到问题
这是我的ViewCell的完整代码
class ListViewTemplateGrid : ViewCell
{
public ListViewTemplateGrid(){
TapGestureRecognizer tgr = new TapGestureRecognizer();
tgr.Tapped += async (object sender, EventArgs e) => {
try {
await Application.Current.MainPage.DisplayAlert("Article", ((ListViewModel)this.BindingContext).Description, "Ok");
}
catch(Exception ex){
await Application.Current.MainPage.DisplayAlert("Error", ex.Message, "Ok");
}
};
Label labelDescription = new Label() {VerticalOptions = LayoutOptions.Center};
labelDescription.SetBinding(Label.TextProperty, "Description");
labelDescription.GestureRecognizers.Add(tgr);
Label labelQty = new Label() { VerticalOptions = LayoutOptions.Center, HorizontalOptions = LayoutOptions.Center };
labelQty.SetBinding(Label.TextProperty, "Qty");
Label labelOrdered = new Label() { VerticalOptions = LayoutOptions.Center, HorizontalOptions = LayoutOptions.Center };
labelOrdered.SetBinding(Label.TextProperty, "Ordered");
// Add controls to the grid
Grid grid = CreateGrid();
grid.Children.Add(labelDescription, 0,1,0,1);
grid.Children.Add(SeparatorV(), 1, 2, 0, 1);
grid.Children.Add(labelQty, 2, 3, 0, 1);
grid.Children.Add(SeparatorV(), 3, 4, 0, 1);
grid.Children.Add(labelOrdered, 4, 5, 0, 1);
grid.Children.Add(SeparatorH(), 0, 5, 1, 2);
this.View = grid;
}
}
如果要切换到命令
,可以使用命令参数
,然后必须直接点击图像。或者您可以尝试使用图像按钮,也可以设置CommandParameter
,如果您要切换到Command
,您可以使用CommandParameter
,然后必须直接点击图像。或者您可以尝试使用图像按钮,也可以设置CommandParameter
,谢谢。当我运行这个示例时,在“xxx.ViewModel”上找不到类似“Command”的属性。我应该为TapCommand声明BindableProperty吗?谢谢。当我运行这个示例时,在“xxx.ViewModel”上找不到类似“Command”的属性。我应该为TapCommand声明BindableProperty吗?