.NET Maui CollectionView:如何仅显示有值的属性行(隐藏空值行)
.NET Maui CollectionView 隐藏空值属性行实现方案
要实现仅显示非空属性行的需求,优先用XAML结合转换器或触发器的方式处理,以下是两种可行方案:
方案一:使用值转换器(推荐,覆盖所有空值场景)
这种方式能统一处理null、空字符串、全空格的情况,复用性强。
步骤1:实现字符串空值转换器
创建一个StringNullOrEmptyConverter,判断字符串是否为空或空白:
using System.Globalization; using Microsoft.Maui.Controls; namespace YourApp.Converters; public class StringNullOrEmptyConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { return string.IsNullOrWhiteSpace(value as string); } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); } }
步骤2:在XAML中注册转换器
在页面的资源字典里声明转换器:
<ContentPage.Resources> <converters:StringNullOrEmptyConverter x:Key="StringNullOrEmptyConverter"/> </ContentPage.Resources>
步骤3:修改CollectionView模板
用VerticalStackLayout替代Grid(自动适配高度,隐藏元素后不占空间),给每个属性对应的Label添加触发器,根据转换器返回值控制可见性:
<CollectionView ItemsSource="{Binding People}"> <CollectionView.ItemTemplate> <DataTemplate x:DataType="model:Person"> <Frame Margin="8" Padding="8"> <VerticalStackLayout Spacing="4"> <!-- 姓名行(若姓名可能为空,也可添加相同触发器) --> <Label Text="{Binding Name}" FontAttributes="Bold"/> <!-- 收藏电影:非空才显示 --> <Label Text="{Binding FavoriteMovie}"> <Label.Triggers> <DataTrigger TargetType="Label" Binding="{Binding FavoriteMovie, Converter={StaticResource StringNullOrEmptyConverter}}" Value="True"> <Setter Property="Visibility" Value="Collapsed"/> </DataTrigger> </Label.Triggers> </Label> <!-- 收藏书籍:非空才显示 --> <Label Text="{Binding FavoriteBook}"> <Label.Triggers> <DataTrigger TargetType="Label" Binding="{Binding FavoriteBook, Converter={StaticResource StringNullOrEmptyConverter}}" Value="True"> <Setter Property="Visibility" Value="Collapsed"/> </DataTrigger> </Label.Triggers> </Label> </VerticalStackLayout> </Frame> </DataTemplate> </CollectionView.ItemTemplate> </CollectionView>
方案二:直接用DataTrigger(无需转换器,仅覆盖null和空字符串)
如果不需要处理全空格的场景,可以直接给Label添加两个触发器,分别判断null和空字符串:
<Label Text="{Binding FavoriteMovie}"> <Label.Triggers> <DataTrigger TargetType="Label" Binding="{Binding FavoriteMovie}" Value="{x:Null}"> <Setter Property="Visibility" Value="Collapsed"/> </DataTrigger> <DataTrigger TargetType="Label" Binding="{Binding FavoriteMovie}" Value=""> <Setter Property="Visibility" Value="Collapsed"/> </DataTrigger> </Label.Triggers> </Label>
注意事项
- 确保
Person类实现INotifyPropertyChanged,属性变更时UI能自动更新(比如从空值变为有效值时,Label会自动显示):
using System.ComponentModel; using System.Runtime.CompilerServices; namespace YourApp.Models; public class Person : INotifyPropertyChanged { private string _firstname; private string _lastname; private string _favoriteMovie; private string _favoriteBook; public string Firstname { get => _firstname; set => SetProperty(ref _firstname, value); } public string Lastname { get => _lastname; set => SetProperty(ref _lastname, value); } // 组合姓名的计算属性 public string Name => $"{Firstname} {Lastname}".Trim(); public string FavoriteMovie { get => _favoriteMovie; set => SetProperty(ref _favoriteMovie, value); } public string FavoriteBook { get => _favoriteBook; set => SetProperty(ref _favoriteBook, value); } public event PropertyChangedEventHandler PropertyChanged; protected void SetProperty<T>(ref T backingStore, T value, [CallerMemberName] string propertyName = "") { if (EqualityComparer<T>.Default.Equals(backingStore, value)) return; backingStore = value; OnPropertyChanged(propertyName); } protected void OnPropertyChanged([CallerMemberName] string propertyName = "") { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
- ViewModel中的
People需用ObservableCollection<Person>类型,确保集合变更时UI同步更新。
内容的提问来源于stack exchange,提问作者Bob
相关产品推荐
相关产品推荐

