嵌套BindableLayout中TapGestureRecognizer绑定内层子集合项如何实现
这个需求完全可以实现,出现绑定结果不符合预期的问题,核心原因是绑定上下文的作用域不匹配:你将TapGestureRecognizer加在了设置BindableLayout.ItemsSource="{Binding Class1}"的宿主StackLayout上,该宿主本身的BindingContext继承自外层,依然是Classes集合的单个项。只有BindableLayout根据ItemsSource自动生成的子元素,BindingContext才会对应到Class1集合的单个项。
解决方案1:调整手势挂载位置(推荐)
将内层的内容放到BindableLayout.ItemTemplate中,再把TapGestureRecognizer挂载到ItemTemplate内部的根布局上,此时{Binding .}就能正确指向当前点击的Class1集合项。
正确的代码示例如下:
<StackLayout BindableLayout.ItemsSource="{Binding Classes}"> <BindableLayout.ItemTemplate> <DataTemplate> <!-- 外层Classes单个项的其他业务内容 --> .... <!-- 内层绑定Class1集合的宿主布局 --> <StackLayout BindableLayout.ItemsSource="{Binding Class1}"> <BindableLayout.ItemTemplate> <DataTemplate> <!-- 该布局的BindingContext对应Class1集合的单个项 --> <StackLayout> <!-- Class1单个项的展示内容 --> ... <!-- 手势挂载到ItemTemplate内的布局上 --> <StackLayout.GestureRecognizers> <TapGestureRecognizer Tapped="Class_Tapped" CommandParameter="{Binding .}" /> </StackLayout.GestureRecognizers> </StackLayout> </DataTemplate> </BindableLayout.ItemTemplate> </StackLayout> </DataTemplate> </BindableLayout.ItemTemplate> </StackLayout>
解决方案2:直接在事件中取值
如果不想调整现有XAML结构,可以跳过CommandParameter,直接在Tapped事件的处理逻辑中获取绑定项:
private void Class_Tapped(object sender, TappedEventArgs e) { // 触发点击的元素的BindingContext就是对应的Class1集合项 var targetClass1Item = (sender as VisualElement)?.BindingContext; // 后续业务逻辑 }
内容的提问来源于stack exchange,提问作者Kasper Sommer
相关产品推荐
相关产品推荐

