Xamarin.Forms中OnSelectTemplate能否为多个CollectionView返回DataTemplate?
Xamarin.Forms 多CollectionView对应不同DataTemplate的解决方案
OnSelectTemplate的原生设计就是单次调用仅返回单个DataTemplate,本身不支持返回多个值,你可以通过以下两种成熟方案实现两个CollectionView各用对应模板的需求:
方案1:为每个CollectionView创建独立的DataTemplateSelector
- 给每个CollectionView单独实现专属的Selector子类,每个子类的
OnSelectTemplate仅处理对应CollectionView的模板判断逻辑,互不干扰 - 代码示例:
// 第一个CollectionView专属的选择器 public class FirstCollectionTemplateSelector : DataTemplateSelector { // 声明第一个CollectionView需要用到的所有模板 public DataTemplate TemplateA { get; set; } public DataTemplate TemplateB { get; set; } protected override DataTemplate OnSelectTemplate(object item, BindableObject container) { // 仅编写第一个CollectionView的模板匹配逻辑 return item is FirstModelTypeA ? TemplateA : TemplateB; } } // 第二个CollectionView专属的选择器 public class SecondCollectionTemplateSelector : DataTemplateSelector { // 声明第二个CollectionView需要用到的所有模板 public DataTemplate TemplateC { get; set; } public DataTemplate TemplateD { get; set; } protected override DataTemplate OnSelectTemplate(object item, BindableObject container) { // 仅编写第二个CollectionView的模板匹配逻辑 return item is SecondModelTypeC ? TemplateC : TemplateD; } }
- 使用时在XAML中分别给两个CollectionView的
ItemTemplate属性绑定对应Selector的实例即可。
方案2:共用同一个Selector,通过container参数区分所属CollectionView
OnSelectTemplate的第二个参数container就是当前触发模板选择的CollectionView实例,你可以给两个CollectionView设置不同的StyleId作为标识,在方法内判断标识后返回对应模板- 代码示例:
public class SharedTemplateSelector : DataTemplateSelector { // 第一个CollectionView的模板 public DataTemplate FirstTempA { get; set; } public DataTemplate FirstTempB { get; set; } // 第二个CollectionView的模板 public DataTemplate SecondTempC { get; set; } public DataTemplate SecondTempD { get; set; } protected override DataTemplate OnSelectTemplate(object item, BindableObject container) { var currentCollection = container as CollectionView; if (currentCollection == null) return null; // 根据StyleId判断是哪个CollectionView调用 if (currentCollection.StyleId == "FirstCollection") { return item is FirstModelTypeA ? FirstTempA : FirstTempB; } else if (currentCollection.StyleId == "SecondCollection") { return item is SecondModelTypeC ? SecondTempC : SecondTempD; } return null; } }
- 使用时先给两个CollectionView分别设置
StyleId为对应的值,再绑定同一个Selector实例即可。
选型建议
优先选择方案1,逻辑拆分清晰,后续修改两个CollectionView的模板规则不会互相影响,也不需要每次调用都做容器判断,性能更优。
内容的提问来源于stack exchange,提问作者Steven-Carrot
相关产品推荐
相关产品推荐

