问题描述
我正在尝试使用此 link 中指定的 CollectionView 和 CarouselView 在 Xamarin.Forms 中创建可滚动选项卡。我需要根据标题中选择的 Tab 在 CarouselView 中加载不同的 ContentView。
我像下面这样尝试,但 ContentView 没有显示..
以下是xaml代码:
<Grid x:DataType="{x:Null}" RowSpacing="0">
<Grid.RowDeFinitions>
<RowDeFinition Height="45" />
<RowDeFinition Height="45" />
<RowDeFinition Height="*" />
</Grid.RowDeFinitions>
<CollectionView
x:Name="CustomTabsView"
Grid.Row="1"
HorizontalScrollBarVisibility="Never"
ItemSizingStrategy="MeasureAllItems"
ItemsSource="{Binding TabVms}"
ItemsUpdatingScrollMode="KeepItemsInView"
SelectedItem="{Binding CurrentTabVm,Mode=TwoWay}"
SelectionMode="Single"
VerticalScrollBarVisibility="Never">
<CollectionView.ItemsLayout>
<LinearItemsLayout Orientation="Horizontal" />
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="local:Tabviewmodel">
<Grid RowSpacing="0">
<Grid.RowDeFinitions>
<RowDeFinition Height="*" />
<RowDeFinition Height="3" />
</Grid.RowDeFinitions>
<Label
x:Name="TitleLabel"
Grid.Row="0"
Padding="15,0"
FontAttributes="Bold"
FontSize="Small"
HeightRequest="50"
HorizontalTextAlignment="Center"
Text="{Binding Title}"
TextColor="White"
VerticalTextAlignment="Center" />
<BoxView
x:Name="ActiveIndicator"
Grid.Row="1"
BackgroundColor="Red"
IsVisible="{Binding IsSelected,Mode=TwoWay}" />
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
<CarouselView
Grid.Row="2"
CurrentItem="{Binding CurrentTabVm,Mode=TwoWay}"
CurrentItemChanged="CarouselView_CurrentItemChanged"
HorizontalScrollBarVisibility="Never"
IsScrollAnimated="True"
IsSwipeEnabled="True"
ItemsSource="{Binding TabVms}"
VerticalScrollBarVisibility="Never">
<CarouselView.ItemTemplate>
<DataTemplate x:DataType="local:Tabviewmodel">
<ContentView
x:Name="dynamiccontent"
BackgroundColor="White"
Content="{Binding DynamicContentView,Mode=TwoWay}" />
</DataTemplate>
</CarouselView.ItemTemplate>
</CarouselView>
</Grid>
private void CarouselView_CurrentItemChanged(object sender,CurrentItemChangedEventArgs e)
{
var x = e.CurrentItem as TabItem;
var viewmodel = BindingContext as xxxviewmodel;
if(x.Header == Tab1)
{
viewmodel.TabVms[0].DynamicContentView = new Page1();
}
if(x.Header == Tab2)
{
viewmodel.TabVms[1].DynamicContentView = new Page2();
}
}
感谢任何帮助!
解决方法
您可以使用 DataTemplateSelector
。
创建 DataTemplateSelector:
class DymaicDataTemplateSelector : DataTemplateSelector
{
public DataTemplate Tab1Template { get; set; }
public DataTemplate Tab2Template { get; set; }
protected override DataTemplate OnSelectTemplate(object item,BindableObject container)
{
return ((TabViewModel)item).Header == "Tab1" ? Tab1Template : Tab2Template;
}
}
在 XAML 中使用 DataTemplateSelector:
<ContentPage.Resources>
<ResourceDictionary>
<DataTemplate x:Key="tab1Template" x:DataType="local:TabViewModel">
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Label
Grid.Row="0"
Margin="10"
LineBreakMode="WordWrap"
Text="{Binding Content}"
TextColor="Red"
VerticalTextAlignment="Center" />
</Grid>
</DataTemplate>
<DataTemplate x:Key="tab2Template" x:DataType="local:TabViewModel">
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Label
Grid.Row="0"
Margin="10"
LineBreakMode="WordWrap"
Text="{Binding Content}"
TextColor="Green"
VerticalTextAlignment="Center" />
</Grid>
</DataTemplate>
<local:DymaicDataTemplateSelector
x:Key="dymaicDataTemplateSelector"
Tab1Template="{StaticResource tab1Template}"
Tab2Template="{StaticResource tab2Template}" />
</ResourceDictionary>
</ContentPage.Resources>
将其分配给 ItemTemplate 属性:
<CarouselView
Grid.Row="2"
CurrentItem="{Binding CurrentTabVm,Mode=TwoWay}"
CurrentItemChanged="CarouselView_CurrentItemChanged"
HorizontalScrollBarVisibility="Never"
IsScrollAnimated="True"
IsSwipeEnabled="True"
ItemTemplate="{StaticResource dymaicDataTemplateSelector}"
ItemsSource="{Binding TabVms}"
VerticalScrollBarVisibility="Never" />