Xamarin Forms:如何更改 FlyoutItem.Icon 的颜色 Selected/Deselected?

Xamarin Forms: How Can I Change the FlyoutItem.Icon's Color When It Is Selected/Deselected?

我正在使用 Material Design Font Icons 作为我项目的图标源。问题是,因为它是 font,所以它在选择时和取消选择时需要不同的颜色(如图所示 - 取消选择的白色图标有白色图标,这不是很棒)。

如何修改 Style 以像更改文本和背景颜色一样更改图标的颜色?

<!-- redacted because it would've never worked -->

编辑 1:

共识是使用 VSM 不会起作用,因为它不是从 VisualElement 派生的。我已经使用 Trigger 让它工作 - 但我对实现不满意。这有效:

<Shell.Resources>
<ResourceDictionary>
<Style TargetType="FlyoutItem" BasedOn="{StaticResource BaseStyle}">
    <Style.Triggers>
        <Trigger TargetType="FlyoutItem" Property="IsChecked" Value="True">
            <Setter Property="Title" Value="Checked" />
            <Setter Property="FlyoutIcon" >
                <Setter.Value>
                    <FontImageSource FontFamily="MaterialDesignIconFont"
                                        Glyph="{StaticResource InformationOutlineGlyph}"
                                        Color="White" />
                </Setter.Value>
            </Setter>
        </Trigger>
    </Style.Triggers>
</Style>

</ResourceDictionary>
</Shell.Resources>

    
<FlyoutItem Title="About" >
    <FlyoutItem.Icon>
        <FontImageSource FontFamily="MaterialDesignIconFont"
                            Glyph="{StaticResource InformationOutlineGlyph}"
                            Color="Green" />
    </FlyoutItem.Icon>

    <ShellContent Route="AboutPage" ContentTemplate="{DataTemplate local:AboutPage}" />
</FlyoutItem>

...但是如您所见,我必须设置整个 FontImageSource 值 - 其中包含 Glyph 属性 - 所以我必须重复此 Style 每次 FlyoutItem.

如何重写此 Style 使其可重复使用并且只更改颜色,而不更改其他属性?

创建 Material Design Icons.

 <Application.Resources>
    <ResourceDictionary>
        <Color x:Key="fgColor">#66169C</Color>
        <Color x:Key="bgColor">#FFFFFF</Color>
        <Color x:Key="OverDueItem">#FF1C07</Color>

        <OnPlatform x:Key="Material" x:TypeArguments="x:String">
            <On Platform="iOS" Value="Material Design Icons" />
            <On Platform="Android" Value="materialdesignicons-webfont.ttf#Material Design Icons" />
        </OnPlatform>

        <Style x:Key="MaterialIcons" TargetType="{x:Type Label}">
            <Setter Property="FontFamily" Value="{DynamicResource Material}" />
            <Setter Property="FontSize" Value="100" />
            <Setter Property="HorizontalOptions" Value="Center" />
            <Setter Property="VerticalOptions" Value="Center" />
            <Setter Property="TextColor" Value="{DynamicResource fgColor}" />
            <Setter Property="FontSize" Value="Large" />
        </Style>
    </ResourceDictionary>
</Application.Resources>

有关 Material 设计图标的更多详细信息,您可以从 GitHub 下载。 https://github.com/WendyZang/Test/tree/master/MaterialDesignIcons/App2

然后创建样式以在您选择时更改背景颜色。

  <Style x:Key="FloutItemStyle" TargetType="Grid">
        <Setter Property="VisualStateManager.VisualStateGroups">
            <VisualStateGroupList>
                <VisualStateGroup x:Name="CommonStates">
                    <VisualState x:Name="Normal" />
                    <VisualState x:Name="Selected">
                        <VisualState.Setters>
                            <Setter Property="BackgroundColor" Value="Accent" />

                        </VisualState.Setters>
                    </VisualState>
                </VisualStateGroup>
            </VisualStateGroupList>
        </Setter>
    </Style>

使用 Triggers 更改标签文本颜色。

 <Shell.ItemTemplate>
    <DataTemplate>
        <Grid x:Name="grid" Style="{StaticResource FloutItemStyle}">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="0.2*" />
                <ColumnDefinition Width="0.8*" />

            </Grid.ColumnDefinitions>
           
            <Label Style="{StaticResource MaterialIcons}" Text="&#xf001;">
                <Label.Triggers>
                    <DataTrigger
                        Binding="{Binding Source={x:Reference grid}, Path=BackgroundColor}"
                        TargetType="Label"
                        Value="Accent">
                        <Setter Property="TextColor" Value="White" />
                    </DataTrigger>
                </Label.Triggers>
            </Label>
            <Label
                Grid.Column="1"
                FontAttributes="Italic"
                Text="{Binding Title}"
                VerticalTextAlignment="Center">
                <Label.Triggers>
                    <DataTrigger
                        Binding="{Binding Source={x:Reference grid}, Path=BackgroundColor}"
                        TargetType="Label"
                        Value="Accent">
                        <Setter Property="TextColor" Value="White" />
                    </DataTrigger>
                </Label.Triggers>
            </Label>
        </Grid>
    </DataTemplate>
</Shell.ItemTemplate>

截图:

更新:

变化:

<Setter Property="TextColor" Value="White" />

收件人:

 <Setter Property="BackgroundColor" Value="Yellow" />

shell 项模板的全部触发器。

 <Label.Triggers>
                    <DataTrigger
                        Binding="{Binding Source={x:Reference grid}, Path=BackgroundColor}"
                        TargetType="Label"
                        Value="Accent">
                        <!--<Setter Property="TextColor" Value="White" />-->
                        <Setter Property="BackgroundColor" Value="Yellow" />
                    </DataTrigger>
                </Label.Triggers>

截图:

我也遇到了同样的问题,解决方法如下

创建一个带有附加 IconGlyphProperty

的自定义浮出控件
class FlyoutItemIconFont : FlyoutItem
{
    public static readonly BindableProperty IconGlyphProperty = BindableProperty.Create(nameof(IconGlyphProperty), typeof(string), typeof(FlyoutItemIconFont), string.Empty);
    public string IconGlyph
    {
        get { return (string)GetValue(IconGlyphProperty); }
        set { SetValue(IconGlyphProperty, value); }
    }
}

创建一个带有两个标签和 VisualStateManager 的 FlyoutItemTemplate

<Shell.ItemTemplate>
    <DataTemplate>
        <Grid>
            <VisualStateManager.VisualStateGroups>
                <VisualStateGroupList>
                    <VisualStateGroup x:Name="CommonStates">
                        <VisualState x:Name="Normal">
                            <VisualState.Setters>
                                <Setter Property="BackgroundColor" Value="White" />
                                <Setter TargetName="FlyoutItemLabel" Property="Label.TextColor" Value="{StaticResource Primary}" />
                            </VisualState.Setters>
                        </VisualState>
                        <VisualState x:Name="Selected">
                            <VisualState.Setters>
                                <Setter Property="BackgroundColor" Value="{StaticResource Primary}" />
                                <Setter TargetName="FlyoutItemLabel" Property="Label.TextColor" Value="White" />
                            </VisualState.Setters>
                        </VisualState>
                    </VisualStateGroup>
                </VisualStateGroupList>
            </VisualStateManager.VisualStateGroups>

            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="0.2*" />
                <ColumnDefinition Width="0.8*" />
            </Grid.ColumnDefinitions>
            <Label x:Name="FlyoutItemIcon"
                FontFamily="MaterialDesignFont"       
                Text="{Binding IconGlyph}"
                TextColor="{Binding Source={x:Reference FlyoutItemLabel} ,Path=TextColor}"
                FontSize="30"
                Margin="5"/>
            <Label x:Name="FlyoutItemLabel"
                Grid.Column="1"        
                Text="{Binding Title}"
                VerticalTextAlignment="Center" />
        </Grid>
    </DataTemplate>
</Shell.ItemTemplate> 

将 AppShell.xaml 中的原始 FlyoutItem 替换为自定义 FlyoutItem

<controls:FlyoutItemIconFont Title="About" IconGlyph="{StaticResource IconInfo}">
    <ShellContent Route="AboutPage" ContentTemplate="{DataTemplate local:AboutPage}" />
</controls:FlyoutItemIconFont>

<controls:FlyoutItemIconFont Title="Browse" IconGlyph="{StaticResource IconListBulleted}">
    <ShellContent Route="ItemsPage" ContentTemplate="{DataTemplate local:ItemsPage}" />
</controls:FlyoutItemIconFont>

将 BaseStyle 添加到 customFlyouItem

<Shell.Resources>
    <ResourceDictionary>
        <x:String x:Key="IconInfo">&#xF02FD;</x:String>
        <x:String x:Key="IconListBulleted">&#xF0279;</x:String>
        ...
        <Style TargetType="controls:FlyoutItemIconFont" BasedOn="{StaticResource BaseStyle}"/>
    </ResourceDictionary>
</Shell.Resources>

这是结果 FlyoutItem with IconFont with different Colors for selected und deselected Item