如何创建继承CollectionView的自定义控件?控件无显示问题排查
解决思路及修正方案
你的自定义CollectionView不显示内容主要有两个核心问题,以下是具体修正步骤:
1. 修正ItemsSource的绑定源
你当前的ItemsSource绑定未指定源,默认会去控件的BindingContext中查找Monkeys属性,而非控件自身的Monkeys属性。需要明确绑定源为控件本身:
// 替换原来的绑定代码 this.SetBinding(ItemsSourceProperty, new Binding(nameof(Monkeys)) { Source = this });
2. 添加布局高度约束
在VerticalStackLayout中,CollectionView如果没有明确的高度设置,会因布局空间分配问题被压缩成0高度。可通过两种方式解决:
方法一:在控件构造函数中设置默认高度
public CustomCollectionView() { // ... 其他代码 ... HeightRequest = 200; // 给控件一个默认显示高度 }
方法二:在XAML使用时指定高度
<local:CustomCollectionView HeightRequest="200" />
完整修正后的CustomCollectionView代码
public class CustomCollectionView : CollectionView { public static readonly BindableProperty MonkeysProperty = BindableProperty.Create( nameof(Monkeys), typeof(ObservableCollection<MonkeyViewModel>), typeof(CustomCollectionView)); public ObservableCollection<MonkeyViewModel> Monkeys { get => (ObservableCollection<MonkeyViewModel>)GetValue(MonkeysProperty); set => SetValue(MonkeysProperty, value); } public CustomCollectionView() { Monkeys = new ObservableCollection<MonkeyViewModel>() { new MonkeyViewModel("Monkey1"), new MonkeyViewModel("Monkey2") }; var linearItemsLayout = new LinearItemsLayout(ItemsLayoutOrientation.Vertical) { ItemSpacing = 8, }; ItemsLayout = linearItemsLayout; // 修正绑定源,指向控件自身的Monkeys属性 this.SetBinding(ItemsSourceProperty, new Binding(nameof(Monkeys)) { Source = this }); ItemTemplate = new DataTemplate(() => { Grid grid = new Grid { Padding = 10, BackgroundColor = Colors.Red }; grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto }); grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto }); Label nameLabel = new Label { FontAttributes = FontAttributes.Bold }; nameLabel.SetBinding(Label.TextProperty, "Name"); grid.Add(nameLabel, 0, 0); // 调整列索引,避免左侧空出不必要的空间 return grid; }); // 添加默认高度,确保控件有足够空间显示 HeightRequest = 200; } } public partial class MonkeyViewModel : ObservableObject { [ObservableProperty] private string _name; public MonkeyViewModel(string name) { Name = name; } }
额外优化点
- 原ItemTemplate中定义了两列但仅使用列1,可删除多余列定义或调整Label到列0,避免内容偏移。
- 若需后续从外部绑定
Monkeys属性,建议将构造函数中的默认集合移到BindableProperty的默认值中,防止覆盖外部绑定值:
public static readonly BindableProperty MonkeysProperty = BindableProperty.Create( nameof(Monkeys), typeof(ObservableCollection<MonkeyViewModel>), typeof(CustomCollectionView), defaultValue: new ObservableCollection<MonkeyViewModel>() { new MonkeyViewModel("Monkey1"), new MonkeyViewModel("Monkey2") });
内容的提问来源于stack exchange,提问作者Toto
相关产品推荐
相关产品推荐

