XAML 如何为所选CollectionView项目设置文本颜色?

chhqkbe1  于 2023-11-14  发布在  其他
关注(0)|答案(2)|浏览(94)

以下是我的CollectionView:

<CollectionView 
                    Margin="5,5,5,15"
                    ItemSizingStrategy="MeasureAllItems"
                    ItemsSource="{Binding Languages}"
                    SelectedItem="{Binding SelectedLanguage, Mode=TwoWay}"
                    SelectionChangedCommand="{Binding LanguageChangedCommand}"
                    SelectionMode="Single">
                <CollectionView.ItemsLayout>
                    <GridItemsLayout Orientation="Vertical" />
                </CollectionView.ItemsLayout>
                <CollectionView.ItemTemplate>
                    <DataTemplate x:DataType="language:CultureInfo">
                        <ContentView Padding="5" >
                            <Grid ColumnDefinitions="*,3*">
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="40" />
                                </Grid.RowDefinitions>
                                <Image Source="{Binding TwoLetterISOLanguageName, StringFormat='flag_{0}.png'}" Grid.Column="0" HorizontalOptions="Start" />
                                <Label Text="{Binding DisplayName}" Grid.Column="1" HorizontalOptions="Start" VerticalOptions="Center" />
                            </Grid>
                        </ContentView>
                    </DataTemplate>
                </CollectionView.ItemTemplate>
            </CollectionView>

字符串
这是我的风格:

<Style TargetType="ContentView">
    <Setter Property="VisualStateManager.VisualStateGroups">
        <VisualStateGroupList>
            <VisualStateGroup x:Name="CommonStates">
                <VisualState x:Name="Normal">
                    <VisualState.Setters>
                        <Setter Property="BackgroundColor" Value="Transparent" />
                    </VisualState.Setters>
                </VisualState>
                <VisualState x:Name="Selected">
                    <VisualState.Setters>
                        <Setter Property="BackgroundColor" Value="{StaticResource LaticreteColor}" />
                    </VisualState.Setters>
                </VisualState>
            </VisualStateGroup>
        </VisualStateGroupList>
    </Setter>
</Style>


这里我设置了所选项目的背景颜色,但是我还需要设置所选项目的文本颜色,并且TextColor属性不存在:
无法解析类型“ContentView“上的属性“TextColor”(缺少属性或缺少访问器)。
如何才能做到这一点?

yizd12fk

yizd12fk1#

要实现该效果,您可以使用VisualStateManager.VisualStateGroups使其工作。请尝试为Label添加x:Name,然后使用为Label设置TextColor。请参阅在多个元素上设置状态。
请参考下面的示例代码:

<ContentPage.Resources>
       <Style TargetType="ContentView">
            <Setter Property="VisualStateManager.VisualStateGroups">
                <VisualStateGroupList>
                    <VisualStateGroup Name="CommonStates">

                        <VisualState x:Name="Normal">
                            <VisualState.Setters>
                                <Setter Property="BackgroundColor" Value="Transparent" />
                            </VisualState.Setters>
                        </VisualState>

                        <VisualState Name="Selected">
                            <VisualState.Setters>
                                <Setter Property="BackgroundColor" Value="Yellow" />
                                <Setter TargetName="label" Property="Label.TextColor" Value="Red" />
                            </VisualState.Setters>
                        </VisualState>
                    </VisualStateGroup>
                </VisualStateGroupList>
               
            </Setter>          
        </Style>
</ContentPage.Resources>
<CollectionView ItemsSource="{Binding Monkeys}"
                        SelectionMode="Single"
                        SelectionChanged="OnCollectionViewSelectionChanged">
            <CollectionView.ItemTemplate>
                <DataTemplate>
                    <ContentView Padding="5">
                        <Grid Padding="10">  
                        <Grid.RowDefinitions>
                            <RowDefinition Height="Auto" />
                            <RowDefinition Height="Auto" />
                        </Grid.RowDefinitions>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="Auto" />
                            <ColumnDefinition Width="Auto" />
                        </Grid.ColumnDefinitions>
                        <Image Grid.RowSpan="2"
                               Source="{Binding ImageUrl}"
                               Aspect="AspectFill"
                               HeightRequest="60"
                               WidthRequest="60" />
                        <Label Grid.Column="1"
                               Text="{Binding Name}"
                               FontAttributes="Bold" />
                        <Label Grid.Row="1"
                               Grid.Column="1"
                               
                               x:Name="label"
                               Text="{Binding Location}"
                               FontAttributes="Italic"
                               VerticalOptions="End" />
                    </Grid>
                    </ContentView>
                </DataTemplate>
            </CollectionView.ItemTemplate>
</CollectionView>

输出:


的数据

gcxthw6b

gcxthw6b2#

解决方案是将VisualStateGroup直接放置在您需要的DataTemplate区域,因此,您可以将BackgroundColor直接放置在ContentView上,但也可以将TextColor直接放置在Label上。
然而,我发现CollectionView在启动时没有正确显示VisualGroup的一个怪癖/bug。只有在你与CollectionView交互后,你才能看到结果,因此,SelectedLanguages中的任何初始值都不会显示给用户。
解决此问题需要两种变通方法:
1.在应用程序启动时添加约500 ms的延迟,以延迟设置SelectedLanguages
1.将VisualStateGroup替换为Binding(或MultiBinding)。
在这里,我使用了一个简单的CompareToObjectConverter。你会看到这已经被硬编码为只识别字符串,但是,你可以推广到其他类型:

public class CompareToObjectConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        if (values.Length != 4)
            throw new ArgumentException("Must have four values");
        return values[0]?.ToString() == values[1]?.ToString() ? values[2] : values[3];
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

字符串
然后,在XAML中,您可以在Bindings中引用此转换器:

<!-- MainPage.xaml ... -->
<ContentPage>
    <!-- ... -->
    <ContentPage.Resources>
        <ResourceDictionary>
            <local:CompareToObjectConverter x:Key="CompareToObjectConverter"/>
        </ResourceDictionary>
    </ContentPage.Resources>
    <!-- ... -->
    <CollectionView ItemsSource="{Binding Languages}"
                    SelectedItem="{Binding SelectedLanguage, Mode=TwoWay}"
                    SelectionMode="Single">
        <CollectionView.ItemTemplate>
            <DataTemplate>
                <ContentView>
                    <ContentView.BackgroundColor>
                        <MultiBinding Converter="{x:StaticResource CompareToObjectConverter}">
                            <Binding Path="SelectedLanguage.Name" Source="{x:RelativeSource AncestorType={x:Type local:MainPage}}"/>
                            <Binding Path="Name"/>
                            <Binding Path="." Source="{x:Static Colors.LightSteelBlue}"/>
                            <Binding Path="." Source="{x:Static Colors.Transparent}"/>
                        </MultiBinding>
                    </ContentView.BackgroundColor>
                    <Grid ColumnDefinitions="*,*">
                        <Image Source="{Binding TwoLetterISOLanguageName, StringFormat='flag_{0}.png'}"/>
                        <Label Grid.Column="1" Text="{Binding DisplayName}">
                            <Label.TextColor>
                                <MultiBinding Converter="{x:StaticResource CompareToObjectConverter}">
                                    <Binding Path="SelectedLanguage.Name" Source="{x:RelativeSource AncestorType={x:Type local:MainPage}}"/>
                                    <Binding Path="Name"/>
                                    <Binding Path="." Source="{x:Static Colors.White}"/>
                                    <Binding Path="." Source="{x:Static Colors.Black}"/>
                                </MultiBinding>
                            </Label.TextColor>
                        </Label>
                    </Grid>
                </ContentView>
            </DataTemplate>
        </CollectionView.ItemTemplate>
    </CollectionView>
</ContentPage>

相关问题