Xamarin.Forms中如何给CollectionView/ListView内的控件设置x:Name
核心问题原因
位于CollectionView的DataTemplate内的控件无法通过x:Name直接全局访问,本质是因为模板会为每个列表条目重复生成实例,编译阶段不会为模板内控件生成全局的后台代码字段,所以直接设置x:Name无法在后台直接引用。
适配需求的实现方案
你需要的点击爱心按钮播放动画的需求,不需要给控件设置全局名称,用以下两种方案即可实现:
方案1:通过Clicked事件的sender参数获取控件实例(最简单快速)
直接给ImageButton绑定Clicked事件,事件触发时的sender就是你点击的那个ImageButton实例,转类型后即可直接操作动画。
XAML示例代码:
<CollectionView ItemsSource="{Binding YourItemList}"> <CollectionView.ItemTemplate> <DataTemplate> <!-- 列表内其他控件省略 --> <ImageButton Source="heart_empty.png" Command="{Binding ToggleCollectCommand}" CommandParameter="{Binding .}" Clicked="HeartBtn_OnClicked"/> </DataTemplate> </CollectionView.ItemTemplate> </CollectionView>
后台C#示例代码:
private async void HeartBtn_OnClicked(object sender, EventArgs e) { // 直接转换拿到当前点击的爱心按钮实例 var heartBtn = sender as ImageButton; if(heartBtn == null) return; // 自定义点击动画,以下为缩放动画示例 await heartBtn.ScaleTo(1.3, 100); await heartBtn.ScaleTo(1, 100); // 可配合条目数据切换爱心状态 // var currentItem = heartBtn.BindingContext as 你的条目数据类型; // heartBtn.Source = currentItem.IsCollected ? "heart_fill.png" : "heart_empty.png"; }
方案2:用Behavior封装动画(MVVM友好无后台硬编码)
如果采用MVVM架构不想写后台事件代码,可以把动画逻辑封装为Behavior,直接在XAML中附加给ImageButton即可。
第一步:创建动画Behavior类
public class HeartClickAnimationBehavior : Behavior<ImageButton> { protected override void OnAttachedTo(ImageButton button) { base.OnAttachedTo(button); button.Clicked += OnBtnClicked; } protected override void OnDetachingFrom(ImageButton button) { base.OnDetachingFrom(button); button.Clicked -= OnBtnClicked; } private async void OnBtnClicked(object sender, EventArgs e) { var btn = sender as ImageButton; if(btn == null) return; await btn.ScaleTo(1.3, 100); await btn.ScaleTo(1, 100); } }
第二步:XAML中附加Behavior
<ImageButton Source="heart_empty.png" Command="{Binding ToggleCollectCommand}" CommandParameter="{Binding .}"> <ImageButton.Behaviors> <local:HeartClickAnimationBehavior/> </ImageButton.Behaviors> </ImageButton>
注意事项
不建议通过遍历视觉树的方式查找模板内控件,性能差且容易匹配到错误实例,上述两种方案即可完全覆盖收藏+动画的需求。
内容的提问来源于stack exchange,提问作者Jimmy
相关产品推荐
相关产品推荐

