如何在AthleteModel的x:DataTemplate中绑定外部Sports.IsExpanded至IsVisible
问题
我希望将SportsModel类型中的Sports.IsExpanded属性绑定到controls:TappableStack的IsVisible属性,但该控件所在的x:DataTemplate已设置x:DataType为AthleteModel,请问如何访问当前x:DataTemplate数据类型之外的变量?
相关XAML代码示例:
<CollectionView IsGrouped="true" ItemsSource="{x:Binding AthletesPerSportsList}" Margin="0,-15,0,0"> <CollectionView.GroupHeaderTemplate> <DataTemplate x:DataType="model:SportsModel"> <StackLayout BackgroundColor="{x:StaticResource PurpleLight}"> <StackLayout.GestureRecognizers> <TapGestureRecognizer Command="{x:Binding Source={x:Reference Athletes}, Path=BindingContext.SportTappedCommand}" CommandParameter="{x:Binding Sports}"/> </StackLayout.GestureRecognizers> <StackLayout Orientation="Horizontal" Padding="20,10"> <CheckBox IsChecked="{x:Binding Sports.IsSelected}"/> <Label Text="{x:Binding Sports.Name}" FontAttributes="Bold" TextColor="Black" Style="{x:StaticResource MediumTextBold}"/> <Label Grid.Column="1" Margin="10,0" FontFamily="ABC" FontSize="25" Text="{x:Static common:ABCIcon.ArrowDown}" TextColor="Black" HorizontalOptions="EndAndExpand"> <Label.Triggers> <DataTrigger Binding="{x:Binding Sports.IsExpanded}" TargetType="Label" Value="true"> <Setter Property="Text" Value="{x:Static common:ABCIcon.ArrowUp}" /> </DataTrigger> </Label.Triggers> </Label> </StackLayout> <BoxView HeightRequest="1" Color="LightGray" Margin="0,-5,0,0"/> </StackLayout> </DataTemplate> </CollectionView.GroupHeaderTemplate> <CollectionView.ItemTemplate> <DataTemplate x:DataType="model:AthleteModel"> <controls:TappableStack TappedCommand="{x:Binding Source={x:Reference Athletes}, Path=BindingContext.AthleteDetailsCommand}" TappedCommandParameter="{x:Binding AthleteId}" IsVisible="{x:Binding }"> <StackLayout Orientation="Horizontal" Padding="20,10"> <CheckBox IsChecked="{x:Binding IsSelected}"/> <StackLayout Spacing="5"> <Label VerticalOptions="Center" Text="{x:Binding Name}" TextColor="Black" Style="{x:StaticResource SmallText}" FontFamily="RM"/> <Label Margin="0,-5,0,0"> <Label.FormattedText> <FormattedString> <Span Text="{x:Static i18n:Translator.Athelete_Alias}" TextColor="Black" Style="{x:StaticResource SmallText}" FontFamily="RM"/> <Span Text=" : " TextColor="Black" Style="{x:StaticResource SmallText}" FontFamily="RM"/> <Span Text="{x:Binding Alias}" TextColor="Black" Style="{x:StaticResource SmallText}"/> </FormattedString> </Label.FormattedText> </Label> </StackLayout> <Label FontFamily="ABC" FontSize="Large" Text="{x:Static common:ABCIcon.ArrowRight}" TextColor="Black" VerticalOptions="Center" HorizontalOptions="EndAndExpand"/> </StackLayout> <BoxView HeightRequest="1" Color="LightGray"/> </controls:TappableStack> </DataTemplate> </CollectionView.ItemTemplate> </CollectionView>
解决方法
方法一:通过RelativeSource关联父级分组数据
在分组的CollectionView中,每个子项的父级CollectionViewItem的绑定上下文就是对应的SportsModel分组。可以通过RelativeSource向上查找该父级元素,直接绑定目标属性:
<controls:TappableStack TappedCommand="{x:Binding Source={x:Reference Athletes}, Path=BindingContext.AthleteDetailsCommand}" TappedCommandParameter="{x:Binding AthleteId}" IsVisible="{Binding BindingContext.Sports.IsExpanded, RelativeSource={RelativeSource AncestorType={x:Type CollectionViewItem}}}">
方法二:在AthleteModel中添加分组引用
如果业务逻辑允许,在AthleteModel类中新增一个指向所属SportsModel的属性:
// AthleteModel类代码 public SportsModel ParentSports { get; set; }
构建分组数据时,给每个AthleteModel实例赋值该属性,之后就能在XAML中直接绑定:
IsVisible="{Binding ParentSports.Sports.IsExpanded}"
方法三:绑定到CollectionView的GroupBindingContext
利用CollectionView自带的GroupBindingContext属性,通过RelativeSource查找CollectionView并绑定到当前项的分组上下文:
IsVisible="{Binding GroupBindingContext.Sports.IsExpanded, RelativeSource={RelativeSource AncestorType={x:Type CollectionView}}}"
内容的提问来源于stack exchange,提问作者Endeavor
相关产品推荐
相关产品推荐

