【问题标题】:Xamarin Forms: How Can I Change the FlyoutItem.Icon's Color When It Is Selected/Deselected?Xamarin Forms:如何在选择/取消选择 FlyoutItem.Icon 时更改它的颜色?
【发布时间】:2020-12-21 22:17:15
【问题描述】:

我使用 Material Design Font Icons 作为我项目的图标源。问题是,由于它是一种 字体,因此在选择时和取消选择时需要不同的颜色(如图所示 - 取消选择的白色图标有白色图标,这不太好)。

如何修改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 属性 - 所以我必须每次为每个 FlyoutItem 重复此 Style

我怎样才能将这个Style 重写为可重复使用并且只更改颜色,而不更改其他属性?

【问题讨论】:

  • 可能不支持。 “图标”是FlyoutItem 的属性。基于description in visual-state-manager,“从 VisualElement 派生的所有类都支持此视觉状态组”,其中不包括弹出项。
  • 是的,我同意。感谢您的链接。
  • Material Design Font Icons 可以用Triggers 做你想做的事。我稍后会提供代码示例。

标签: xaml xamarin xamarin.forms app.xaml app-shell


【解决方案1】:

我有同样的问题并解决如下

使用额外的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

【讨论】:

    【解决方案2】:

    创建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 Design 图标的更多详细信息,您可以从 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 更改标签TextColor。

     <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 itemtemplate 的全部触发器。

     <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>
    

    截图:

    【讨论】:

    • 你在正确的轨道上,但我需要它与FlyoutItem.Icon 背景颜色一起工作。 FlyoutItem 不像 Label 那样继承自 VisualElement - 所以你不能使用 VSM - 你必须使用触发器。我不知道如何仅更改背景颜色。
    • 我已经更新了回复。如果您只想更改背景颜色,请将触发器中的代码更改为背景颜色。我把颜色改成黄色供你参考。
    • 请查看我的问题的最新编辑。
    • @ScottBaker 我检查了你的编辑。但是对于背景颜色,触发器只在数据模板中使用过一次。不需要为每个 FlyoutItem 每次都重复这个 Style。
    猜你喜欢
    • 2020-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多