【问题标题】:Xamarin.Forms DataTemplateSelector not working for HeaderTemplate in CollectionViewXamarin.Forms DataTemplateSelector 不适用于 CollectionView 中的 HeaderTemplate
【发布时间】:2021-12-27 00:43:05
【问题描述】:

我已经为我的 Collectionviews Header 声明了一些 Datatemplates 以用作模板。

    <ResourceDictionary>
      <!--#region HeaderTemplates-->
      <DataTemplate x:Key="translationHeaderTemplate">
        <Frame x:Name="translationDropTarget" Margin="5">
          <Label Style="{x:StaticResource boldLabelStyle}" Text="{Binding SolutionDisplay}" FontSize="Medium" HorizontalOptions="Center" HeightRequest="50" VerticalOptions="Center" x:Name="FrameLabel"></Label>
          <Frame.GestureRecognizers>
            <DropGestureRecognizer AllowDrop="True" DropCommand="{Binding DropOverCommand}">
            </DropGestureRecognizer>
          </Frame.GestureRecognizers>
        </Frame>
      </DataTemplate>
      <DataTemplate x:Key="pictureHeaderTemplate">
        <Frame x:Name="pictureDropTarget" Margin="5">
          <Image Source="{Binding SolutionIconString}" HorizontalOptions="FillAndExpand" MinimumWidthRequest="50" HeightRequest="100" VerticalOptions="CenterAndExpand" x:Name="FrameImage"></Image>
          <Frame.GestureRecognizers>
            <DropGestureRecognizer AllowDrop="True" DropCommand="{Binding DropOverCommand}">
            </DropGestureRecognizer>
          </Frame.GestureRecognizers>
        </Frame>
      </DataTemplate>
      <DataTemplate x:Key="ttsHeaderTemplate">
        <Frame x:Name="ttsDropTarget" Margin="5">
          <forms:AnimationView x:Name="XAnim" AutoPlay="true" VerticalOptions="CenterAndExpand" RepeatMode="Infinite" HorizontalOptions="CenterAndExpand" Animation="soundIcon.json"
                               Clicked="XAnim_Clicked" ></forms:AnimationView>
          <Frame.GestureRecognizers>
            <DropGestureRecognizer AllowDrop="True" DropCommand="{Binding DropOverCommand}">
            </DropGestureRecognizer>
          </Frame.GestureRecognizers>
        </Frame>
      </DataTemplate>
      <!--#endregion-->
      <DataTemplate x:Key="translationTemplate">
        <Frame HasShadow="True" CornerRadius="15" VerticalOptions="Start" HeightRequest="70">
          <StackLayout>
            <Label
                  Text="{Binding DisplayString}"
                  Style="{x:StaticResource mediumlabelStyle}"
                  VerticalOptions="CenterAndExpand"
                    HorizontalOptions="Center"
                  FontSize="Small">
            </Label>
          </StackLayout>
          <Frame.GestureRecognizers>
            <DragGestureRecognizer
                    DragStartingCommand="{Binding Path=BindingContext.DragStartingCommand, Source={x:Reference ViewCollection}}"
                    DragStartingCommandParameter="{Binding .}"/>
          </Frame.GestureRecognizers>
        </Frame>
      </DataTemplate>
      <vokabelmodul:VocabularyViewTemplateSelector
        x:Key="vocViewTemplateSelector"
        TranslationTemplate="{StaticResource translationHeaderTemplate}"
        PictureTemplate="{StaticResource pictureHeaderTemplate}"
        TTSTemplate="{StaticResource ttsHeaderTemplate}"/>
    </ResourceDictionary>
  </ContentPage.Resources>

我正在尝试使用模板选择器在我的 CollectionView 中使用它:

      <ContentPage.Content>
    <AbsoluteLayout>
      <StackLayout
      AbsoluteLayout.LayoutBounds="0,0,1,1"
      AbsoluteLayout.LayoutFlags="All">
        <Frame>
          <StackLayout>
            <Label Style="{x:StaticResource labelStyle}" FontSize="Small" x:Name="TimerLabel" Text="{Binding Remaining}"></Label>
            <ProgressBar x:Name="Progress" Progress="{Binding Progress}" ProgressColor="Blue"></ProgressBar>
          </StackLayout>
        </Frame>
        <StackLayout x:Name="InnerStack">
          <CollectionView      
          x:Name="ViewCollection"
          ItemsSource="{Binding ViewObjects}"
          VerticalOptions="Center"
          Margin="5"
            ItemTemplate="{StaticResource translationTemplate}"
            HeaderTemplate="{StaticResource vocViewTemplateSelector}"
            Header="{Binding .}"
            >
            <CollectionView.EmptyView>
              <Label Text="No VocabularyItems!" Style="{x:StaticResource boldLabelStyle}"></Label>
            </CollectionView.EmptyView>
            <CollectionView.ItemsLayout>
              <GridItemsLayout
              Orientation="Vertical"
              HorizontalItemSpacing="5"
              VerticalItemSpacing="5"
              Span="2"/>
            </CollectionView.ItemsLayout>
          </CollectionView>
        </StackLayout>
      </StackLayout>
    </AbsoluteLayout>
  </ContentPage.Content>

但是当我运行程序时,我总是收到“System.InvalidOperationException: 'LoadTemplate should not be null'”。

当我像这样直接绑定我的 HeaderTemplate 时:

 HeaderTemplate="{StaticResource someHeaderTemplate}"

效果很好。

我在我的 TemplateSelector 类中添加了一个日志和断点,但 OnSelectTemplate 甚至没有被调用。 我还为我的 ItemTemplate 使用了另一个 Templateselector,它工作得很好。

任何帮助将不胜感激。

【问题讨论】:

    标签: forms xaml xamarin datatemplateselector


    【解决方案1】:
    1. 在你的xaml页面中,你的DataTemplate标签没有添加任何数据或样式,你需要给每个DataTemplate标签添加样式。

    2. 你还没有绑定CollectionView的Header数据。您需要将Header="{Binding ViewObjects}" 添加到您的 CollectionView 标记中。

    这是我的xaml代码供你参考,希望能解决你的问题:

    <ContentPage.Resources>
        <ResourceDictionary>
            <DataTemplate x:Key="someHeaderTemplate">
                <Label Text="aaa" BackgroundColor="LightPink"></Label>
            </DataTemplate>
            <DataTemplate x:Key="someOtherHeaderTemplate">
                <Label Text="bbb" BackgroundColor="Green"></Label>
            </DataTemplate>
            <DataTemplate x:Key="someThirdHeaderTemplate">
                <Label Text="ccc" BackgroundColor="Yellow"></Label>
            </DataTemplate>
            <nameSpace:templateSelector x:Key="templateSelector"
                first="{StaticResource someHeaderTemplate}"
                second="{StaticResource someOtherHeaderTemplate}"
                third="{StaticResource someThirdHeaderTemplate}"/>
        </ResourceDictionary>
    </ContentPage.Resources>
    <StackLayout>
        <CollectionView
          x:Name="ViewCollection"
          Header="{Binding ViewObjects}"
          ItemsSource="{Binding ViewObjects}"
          VerticalOptions="Center"
          Margin="5"
          HeaderTemplate="{StaticResource templateSelector}">
            <CollectionView.ItemTemplate>
                <DataTemplate>
                    <Label></Label>
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>
    </StackLayout>
    

    【讨论】:

    • 感谢您的回复。也许我应该指定,但我在原始代码中的模板确实包含数据。我已经绑定了like Header = {Binding .} 我会相应地编辑我的答案
    • 你应该指向数据源,这与ItemsSource的使用类似。
    • 这有点道理,但恕我直言并非如此。 ItemsSource 绑定在一个 ObservableCollection 上,它是我的视图模型中的一个属性,如果有意义的话,标题应该只绑定在视图模型上
    • 我注意到你更新了你的代码,它仍然出现 System.InvalidOperationException 还是没有值?
    • 是的错误是一样的,我也尝试从 itemssource 中删除绑定并将模板选择器内联添加到 在我看来 HeaderTemplate 不会使用模板选择器。至少不像我打算的那样。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-05-11
    • 2021-07-01
    • 2020-09-29
    • 2019-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多