在 Xamarin Forms 中突出显示 CollectionView 中的选定项目 在您的模型中在数据模板中在代码隐藏中ViewModel

问题描述

我试图用不同的颜色突出显示 collectionview 的选定项目。该代码在 iOS 中运行良好,但在 Android 中不起作用。在 Android 中,第一个项目总是被选中,但当我点击它们时它不会突出显示其他项目。

更新

我发现问题是网格上的 GestureRecognizers,如果我删除它。它的行为符合预期。添加 GestureRecognizers 后,预期行为丢失。

解决方法

如果我将 Grid 包裹在 swipeview 中,它就可以正常工作。但是,当 CollectionView 超过 100 项时问题仍然存在。

第二种解决方法

这对于 CollectionView 中的任意数量的项目都非常有效。在第一个网格内添加第二个网格,并在第二个网格上应用 GestureRecognizers 事件,一切都按预期顺利运行。

Theme.xaml -> 从主题文件获取样式

<Style targettype="Grid" x:Key="ItemTemplateGrid">
        <Setter Property="visualstatemanager.VisualStateGroups">
            <VisualStateGroupList>
                <VisualStateGroup>
                    <VisualState Name="normal"/>
                    <VisualState Name="Selected">
                        <VisualState.Setters>
                            <Setter Property="BackgroundColor" Value="{AppThemeBinding Dark={StaticResource BackgroundSecondaryColorDark},Light={StaticResource BackgroundSecondaryColorLight}}"/>
                        </VisualState.Setters>
                    </VisualState>
                </VisualStateGroup>
            </VisualStateGroupList>
        </Setter>
    </Style>

XAML 页面资源

<DataTemplate x:Key="AndroidAyaItemTemplate">
            <Grid RowDeFinitions="*,Auto" Style="{DynamicResource ItemTemplateGrid}">
                <Grid Grid.Row="0" RowDeFinitions="Auto,Auto,Auto" RowSpacing="0" Padding="10">
                    <Label Grid.Row="0" LineBreakMode="WordWrap" IsVisible="{Binding BindingContext.ShowEnglishVerseNumber,Source={x:Reference MyPage},Converter={StaticResource InverterBooleanConverter}}">
                        <Label.FormattedText>
                            <FormattedString>
                                <Span Text="{Binding arabicText.Aya}" FontSize="{Binding BindingContext.ActivearabicFont.FontSize,Source={x:Reference MyPage}}"
                                          FontFamily="{Binding BindingContext.ActivearabicFont.FontPath,Source={x:Reference MyPage}}"/>
                                <Span Text="{Binding arabicText.arabicAyaNumber,StringFormat='﴿{0}﴾'}"
                                          FontSize="{Binding BindingContext.ActivearabicFont.FontSize,Source={x:Reference MyPage}}"
                                          FontFamily="Sherzad"></Span>
                            </FormattedString>
                        </Label.FormattedText>
                    </Label>
                    <Label Grid.Row="0" LineBreakMode="WordWrap" IsVisible="{Binding BindingContext.ShowEnglishVerseNumber,Source={x:Reference MyPage}}">
                        <Label.FormattedText>
                            <FormattedString>
                                <Span Text="{Binding arabicText.Aya}" FontSize="{Binding BindingContext.ActivearabicFont.FontSize,Source={x:Reference MyPage}}"/>
                                <Span Text="﴿" FontSize="35" FontFamily="Sherzad"></Span>
                                <Span Text="{Binding arabicText.AyaNumber,Converter={StaticResource ZeroToEmptyConverter}}" FontSize="Small"></Span>
                                <Span Text="﴾" FontSize="35" FontFamily="Sherzad"></Span>
                            </FormattedString>
                        </Label.FormattedText>
                    </Label>
                    <Label Grid.Row="1" LineBreakMode="WordWrap" HorizontalTextAlignment="Start" Margin="0,5,5"
                            IsVisible="{Binding BindingContext.ShowTransliteration,Source={x:Reference MyPage}}"
                               FontSize="{Binding BindingContext.TransliterationFontSize,Source={x:Reference MyPage}}"
                               Text="{Binding arabicText.Transliteration}"
                            FlowDirection="LeftToRight">
                    </Label>
                    <Label Grid.Row="2" LineBreakMode="WordWrap" HorizontalTextAlignment="Start"
                            IsVisible ="{Binding BindingContext.TranslationVisible,Source={x:Reference MyPage}}"
                            FontSize="{Binding BindingContext.ActiveTranslationFont.FontSize,Source={x:Reference MyPage}}"
                            FontFamily="{Binding BindingContext.ActiveTranslationFont.FontPath,Source={x:Reference MyPage}}"
                            Text="{Binding AyaTranslation}"
                            FlowDirection="{Binding BindingContext.ActiveTranslationLanguage.FlowDirection,Source={x:Reference MyPage}}"/>
                </Grid>
                <BoxView Grid.Row="1" Style="{DynamicResource HLine}" IsVisible="{Binding BindingContext.ShowHorizentalLine,Source={x:Reference MyPage}}"/>
                <Grid.GestureRecognizers>
                    <TapGestureRecognizer NumberOfTapsrequired="2" Command="{Binding BindingContext.ShareAyaCommand,Source={x:Reference itemView}}" CommandParameter="{Binding .}"/>
                    <SwipeGestureRecognizer Direction="Right" Command="{Binding BindingContext.NextChapterCommand,Source={x:Reference MyPage}}"/>
                    <SwipeGestureRecognizer Direction="Left" Command="{Binding BindingContext.PrevIoUsChapterCommand,Source={x:Reference MyPage}}"/>
                </Grid.GestureRecognizers>
            </Grid>
        </DataTemplate>

集合视图

<CollectionView Grid.Row="0" ItemsSource="{Binding arabicListText}" SelectedItem="{Binding SelectedAya}" SelectionMode="Single" FlowDirection="RightToLeft"
                                    ItemTemplate="{StaticResource AndroidAyaItemTemplate}"
                        x:Name="itemView">
                    <CollectionView.ItemsLayout>
                        <LinearItemsLayout Orientation="Vertical" ItemSpacing="5"/>
                    </CollectionView.ItemsLayout>
                </CollectionView>

如果我从网格中删除样式“ItemTemplateGrid”,它会相应地突出显示每一行,但颜色是操作系统的认颜色。

不需要 swipeview。它应该可以在没有两种解决方法的情况下工作。

解决方法

由于您使用了 SelectedItem="{Binding SelectedAya}" ,您可以在模型中定义一个属性来绑定 DataTemplate 的背景颜色,这样您就不需要不再使用样式字典。

在您的模型中

添加属性

private Color bgColor;
public Color BgColor
{
    get => bgColor;
    set
    {
        if (bgColor!= value)
        {
            bgColor= value;

            foreach(YourModel model in ArabicListText)
            {
                if(mdoel == SelectedAya)
                {
                    if(App.Current.RequestedTheme== OSAppTheme.Dark)
                    {
                        model.BgColor = xxx;
                    }
                    else
                    {
                        model.BgColor = xxx;
                    }
                }
                else
                {
                    model.BgColor = xxx;
                }
            }            

            OnPropertyChanged(nameof(BgColor));
        }
    }
}

在数据模板中

 <Grid RowDefinitions="*,Auto"  BackgroundColor="{Binding BgColor}"  Padding="10">

在代码隐藏中(ViewModel)


private YourModel selectedAya;
public YourModel SelectedAya
{
    get => selectedAya;
    set
    {
        if (selectedAya!= value)
        {
            selectedAya= value;

            

            OnPropertyChanged(nameof(SelectedAya));
        }
    }
}