.NET MAUI ListView绑定不同子类数据出现绑定错误求助
我定义了三个类:
abstract public class PlanPosition { public long Id { get; set; } public Plan? Plan { get; set; } = null; public int Pos { get; set; } } public class AddressPos:PlanPosition { public Address Address { get; set; } public LocomotionType LocomotionType { get; set; } } public class DayPos:PlanPosition { public int Day { get; set; } }
我有一个包含AddressPos或DayPos类型元素的PlanPosition列表,使用带有DataTemplateSelector的ListView时出现大量绑定错误。XAML代码片段如下:
<ContentPage.Resources> <util:DateOnlyToDateTimeConverter x:Key="DateConverter"/> <DataTemplate x:Key="AddressPosTemplate" x:DataType="data:AddressPos"> <ViewCell> <Border HorizontalOptions="Start" WidthRequest="300" Padding="5" Margin="20" StrokeShape="RoundRectangle 10,10,10,10"> <VerticalStackLayout> <HorizontalStackLayout Spacing="5"> <HorizontalStackLayout.Triggers> <DataTrigger TargetType="HorizontalStackLayout" Binding="{Binding Pos}" Value="1"> <Setter Property="IsVisible" Value="False"/> </DataTrigger> </HorizontalStackLayout.Triggers> ... </HorizontalStackLayout> <Label Text="{Binding Name}" FontAttributes="Bold" FontSize="12"/> </VerticalStackLayout> </Border> </ViewCell> </DataTemplate> <DataTemplate x:Key="DayPosTemplate" x:DataType="data:DayPos"> <ViewCell> <Border HorizontalOptions="Start" WidthRequest="100" BackgroundColor="LightGray" Padding="5" Margin="10" StrokeShape="RoundRectangle 10,10,10,10"> <HorizontalStackLayout HorizontalOptions="Center" Spacing="5"> <Image Source="menu_burger.png" HeightRequest="20" VerticalOptions="Center"/> <Label Text="{Binding Day,StringFormat='Tag {0:D}'}" FontAttributes="Bold" VerticalOptions="Center"/> <ImageButton x:Name="delButton" Source="trash.png" HeightRequest="20" IsVisible="False" Padding="0" Margin="0" BackgroundColor="LightGray"/> </HorizontalStackLayout> <VisualStateManager.VisualStateGroups> <VisualStateGroup Name="CommonStates"> <VisualState Name="Normal"> <VisualState.Setters> <Setter TargetName="delButton" Property="ImageButton.IsVisible" Value="False"/> <Setter Property="WidthRequest" Value="100"/> </VisualState.Setters> </VisualState> <VisualState Name="PointerOver"> <VisualState.Setters> <Setter TargetName="delButton" Property="ImageButton.IsVisible" Value="True"/> <Setter Property="WidthRequest" Value="150"/> </VisualState.Setters> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups> </Border> </ViewCell> </DataTemplate> <util:PlanPosDataTemplateSelector x:Key="PosSelector" AddressPos="{StaticResource AddressPosTemplate}" DayPos="{StaticResource DayPosTemplate}"/> </ContentPage.Resources>
ListView的数据源是List<PlanPosition>,不同DataTemplate的x:DataType分别指定为AddressPos或DayPos,但出现类似以下绑定错误:
Schweregrad Anzahl Datenkontext Bindungspfad Ziel Zieltyp Beschreibung Datei Zeile Projekt Fehler 24 PlannerViewModel Pos HorizontalStackLayout.Bound Object 'Pos' property not found on 'TripPlanner.Planner.PlannerViewModel', target property: 'Microsoft.Maui.Controls.HorizontalStackLayout.Bound' E:\NETProjects\Tripplanner\TripPlanner\Planner\PlannerPage.xaml 23 TripPlanner Schweregrad Anzahl Datenkontext Bindungspfad Ziel Zieltyp Beschreibung Datei Zeile Projekt Fehler 14 PlannerViewModel Day Label.Text String 'Day' property not found on 'TripPlanner.Planner.PlannerViewModel', target property: 'Microsoft.Maui.Controls.Label.Text' E:\NETProjects\Tripplanner\TripPlanner\Planner\PlannerPage.xaml 52 TripPlanner
我想知道是不是无法在ListView中显示不同类的项?目前想到的方法是创建一个包含所有子类属性的显示类,但这不符合面向对象思想,求正确的解决方案。
确保DataTemplateSelector实现正确
你的PlanPosDataTemplateSelector必须准确判断项的类型并返回对应模板,示例实现如下:public class PlanPosDataTemplateSelector : DataTemplateSelector { public DataTemplate AddressPos { get; set; } public DataTemplate DayPos { get; set; } protected override DataTemplate OnSelectTemplate(object item, BindableObject container) { return item switch { AddressPos => AddressPos, DayPos => DayPos, _ => base.OnSelectTemplate(item, container) }; } }为ListView的ItemTemplate指定Selector
必须确保ListView的ItemTemplate绑定到你的PosSelector,而非固定模板:<ListView ItemsSource="{Binding YourPlanPositionList}" ItemTemplate="{StaticResource PosSelector}"> <!-- 其他ListView配置 --> </ListView>修复绑定上下文继承问题
错误显示绑定上下文是PlannerViewModel,说明模板内的绑定未正确继承到列表项对象。可以在ViewCell内显式绑定上下文,或者检查父布局是否意外覆盖了绑定上下文:<ViewCell BindingContext="{Binding .}"> <!-- 模板内容 --> </ViewCell>验证x:DataType的命名空间
确认XAML中data:命名空间指向实体类所在的程序集和命名空间,例如:xmlns:data="clr-namespace:TripPlanner.Data;assembly=TripPlanner"修正AddressPos模板中的Name绑定
AddressPos类中没有直接的Name属性,需修改为绑定Address对象的Name属性:<Label Text="{Binding Address.Name}" FontAttributes="Bold" FontSize="12"/>
内容的提问来源于stack exchange,提问作者juergjtreichlerch

