如何使用 WPF 按钮的参数或绑定来更改 XAML 样式的 fa 图标

How to use parameters or binding for WPF buttons to change fa icons in XAML styles

我为 WPF 中的按钮制作了 XAML 样式,用于菜单项。创建菜单列表时,我想根据我放入代码中的参数更改图标(FontAwesome 图标),以保持其整洁,并为按钮中的其他元素使用相同的样式。

但是到目前为止,我发现无法将参数发送到样式。所以我想知道如何实现它。我也试过 Icon="{Binding Path=Icon}" 但我相信这不适用于每个按钮。

我有: All icons are the same

<Button DockPanel.Dock="Top" x:Name="MenuHome" Style="{StaticResource MenuItem}">Home</Button>

我想要什么: All icons are different

<Button DockPanel.Dock="Top" x:Name="MenuHome" Style="{StaticResource MenuItem}" Icon="Home" IconColor="Green">Home</Button>

代码:

    <!-- Menu item button style unclicked -->
    <Style x:Key="MenuItem" TargetType="{x:Type Button}">
        <Setter Property="Height" Value="50"/>
        <Setter Property="Background" Value="#FF33334C"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Button}">
                    <Grid>
                        <Border Background="{TemplateBinding Background}"/>
                        <Grid Name="GridMouseOver" Background="Black" Opacity="0.2" Visibility="Hidden"/>
                        <fa:ImageAwesome Icon="AddressBook" Height="30" Width="30" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="15,0,0,0"/>
                        <TextBlock Text="{TemplateBinding Content}" Foreground="Gainsboro" FontSize="20" TextWrapping="Wrap" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="60,0,0,0"/>
                    </Grid>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter TargetName="GridMouseOver" Property="Visibility" Value="Visible"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>

            </Setter.Value>
        </Setter>
    </Style>
    
    <!-- Sub menu item button style -->
    <Style x:Key="SubMenuItem" TargetType="{x:Type Button}">
        <Setter Property="Height" Value="50"/>
        <Setter Property="Background" Value="#FF33334C"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Button}">
                    <Grid>
                        <Border Background="{TemplateBinding Background}"/>
                        <Grid Name="GridMouseOver" Background="Black" Opacity="0.2" Visibility="Hidden"/>
                        <fa:ImageAwesome Icon="{Binding Path=Icon}" Height="20" Width="20" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="20,0,0,0"/>
                        <TextBlock Text="{TemplateBinding Content}" Foreground="Gainsboro" FontSize="16" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="60,0,0,0"/>
                    </Grid>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter TargetName="GridMouseOver" Property="Visibility" Value="Visible"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>


<!-- Button creation code -->
<Grid>
    <DockPanel>
        <!-- Menu grid -->
        <Grid x:Name="Menu" DockPanel.Dock="Left" Background="#FF33334C">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="200"/>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition  Height="100"/>
                <RowDefinition  Height="1*"/>
            </Grid.RowDefinitions>
            <DockPanel Grid.Row="2" LastChildFill="False">
                <Button DockPanel.Dock="Top" x:Name="MenuHome" Style="{StaticResource MenuItem}">Home</Button>
                <!-- Add visibility Visibility="Collapsed" to the sub menu dock panel-->
                <DockPanel x:Name="SubMenuHome" DockPanel.Dock="Top">
                    <Button DockPanel.Dock="Top" x:Name="SubMenuHome1" Style="{StaticResource SubMenuItem}">Sub Home 1</Button>
                    <Button DockPanel.Dock="Top" x:Name="SubMenuHome2" Style="{StaticResource SubMenuItem}">Sub Home 2</Button>
                </DockPanel>
                <Button DockPanel.Dock="Top" x:Name="MenuProject" Style="{StaticResource MenuItem}">Project</Button>
                <Button DockPanel.Dock="Top" x:Name="MenuTools" Style="{StaticResource MenuItem}">Tools</Button>
            </DockPanel>
        </Grid>
        <Grid x:Name="TitleBar" DockPanel.Dock="Top" Background="#FF33334C">
            <Grid.RowDefinitions>
                <RowDefinition Height="50"/>
            </Grid.RowDefinitions>
        </Grid>
        <Grid x:Name="ChildForm" Background="#FF333346">

        </Grid>
    </DockPanel>

</Grid>

您可以尝试参考以下代码将Icon绑定到Button的Tag内容上。包含两个方法,可以参考.

<Style x:Key="FontAwesome">
        <Setter Property="TextElement.FontFamily" Value="pack://application:,,,/Font/#Font Awesome 5 Free Regular" />
    </Style>
    <Style x:Key="MenuItem" TargetType="{x:Type Button}">
        <Setter Property="Height" Value="50"/>
        <Setter Property="Background" Value="#FF33334C"/>
        <Setter Property="TextElement.FontFamily" Value="pack://application:,,,/Font/#Font Awesome 5 Free Regular" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Button}">
                    <Grid>
                        <Border Background="{TemplateBinding Background}"/>
                        <Grid Name="GridMouseOver" Background="Black" Opacity="0.2" Visibility="Hidden"/>
                        <fa:ImageAwesome Icon="{Binding Tag, RelativeSource={RelativeSource FindAncestor,  AncestorType=Button} }" Height="30" Width="30" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="15,0,0,0"/>
                        <TextBlock Text="{TemplateBinding Content}" Foreground="Gainsboro" FontSize="20" TextWrapping="Wrap" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="60,0,0,0"/>
                    </Grid>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter TargetName="GridMouseOver" Property="Visibility" Value="Visible"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>

            </Setter.Value>
        </Setter>
    </Style>
    <Style x:Key="MenuItem2" TargetType="{x:Type Button}">
        <Setter Property="Height" Value="50"/>
        <Setter Property="Background" Value="#FF33334C"/>
        <Setter Property="TextElement.FontFamily" Value="pack://application:,,,/Font/#Font Awesome 5 Free Regular" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Button}">
                    <Grid>
                        <Border Background="{TemplateBinding Background}"/>
                        <Grid Name="GridMouseOver" Background="Black" Opacity="0.2" Visibility="Hidden"/>
                        <TextBlock Text="{Binding Tag, RelativeSource={RelativeSource FindAncestor,  AncestorType=Button} }" FontSize="22" Margin="14" HorizontalAlignment="Left" VerticalAlignment="Center" Style="{DynamicResource  FontAwesome}" />
                        <TextBlock Text="{TemplateBinding Content}" Foreground="Gainsboro" FontSize="20" TextWrapping="Wrap" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="60,0,0,0"/>
                    </Grid>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter TargetName="GridMouseOver" Property="Visibility" Value="Visible"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>

            </Setter.Value>
        </Setter>
    </Style>

<Grid x:Name="Menu" DockPanel.Dock="Left" Background="#FF33334C">
               ...
               <DockPanel Grid.Row="2" LastChildFill="False">
                <Button DockPanel.Dock="Top" x:Name="MenuHome" Style="{StaticResource MenuItem}" Tag="home">Home</Button>
                <DockPanel x:Name="SubMenuHome" DockPanel.Dock="Top" >
                    <Button DockPanel.Dock="Top" x:Name="SubMenuHome1" Style="{StaticResource SubMenuItem}">Sub Home 1</Button>
                    <Button DockPanel.Dock="Top" x:Name="SubMenuHome2" Style="{StaticResource SubMenuItem}">Sub Home 2</Button>
                </DockPanel>
                <Button DockPanel.Dock="Top" x:Name="MenuProject" Style="{StaticResource MenuItem2}"  Tag="&#xf542;">Project
                </Button>
            </DockPanel>
            </Grid>

结果:

下面是我如何在上面 answer/info 的帮助下改进我的代码。

我实现了 FontAwesome 5 而不是 Nuget 包 FontAwesome.WPF 因为它包含更多图标。

  1. 从网站下载资源文件

    Download Link FA5 Desktop

  2. 在您的项目中创建一个名为 Fonts 的文件夹 (ProjectName.csproj)

    文件夹必须在这个级别,因为首先制作多个文件夹结构 (Fonts/otf/FA5.otf) 对我不起作用。

  3. 如果您愿意,可以将其重命名为更容易输入的名称

    FaFreeSolid 对我来说

  4. 复制到字体文件夹

  5. 将其添加到项目中

    项目菜单 -> 显示所有文件 -> 解决方案资源管理器 -> 右键单击​​ .otf 文件 -> 添加到项目

  6. 打开Windows中的.otf字体文件,查看顶部的名称。暂时复制

  7. 创建资源字典

    RMB ProjectName.csproj -> 添加 -> ResourceDictionary (WPF) -> 将其命名为 FontAwesomeResources

  8. 打开文件并创建一个 FontFamily

    第 1 部分:键=调用它的名称

    第 2 部分:字体文件的路径

    第 3 部分:第 6 点的#FontName

代码:

<FontFamily x:Key="FaFreeSolid">/Fonts/FaFreeSolid.otf#Font Awesome 5 Free</FontFamily>
  1. 转到App.xaml为整个项目调用资源

代码:

    <Application.Resources>
            <ResourceDictionary Source="FontAwesomeResources.xaml"/>  
    </Application.Resources>
  1. 我在文本 属性 的文本块中使用了资源。这个 属性 然后设置图标图像。文本应与网站上的相同。我注意到名称中带有 - 的名称不起作用,因此您必须在文本中使用 &#x 前缀并使用其后面的图标代码。 (例如: = 地址簿)

    FA Cheat Sheet

这部分使“主页”图标显示:

<TextBlock Text="Home" Foreground="DarkRed" FontFamily="{StaticResource FaFreeSolid}" FontSize="30" VerticalAlignment="Center" Margin="15,0,0,0"/>

MainWindow.xaml:

<!-- Menu item button style unclicked -->
    <Style x:Key="btnMenuItem" TargetType="{x:Type Button}">
        <Setter Property="Height" Value="50"/>
        <Setter Property="Background" Value="Transparent"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Button}">
                    <Border Background="{TemplateBinding Background}">
                        <StackPanel Orientation="Horizontal">
                            <Grid Name="GridMouseOver" Background="Black" Opacity="0.2" Visibility="Hidden"/>
                            <TextBlock Text="Home" Foreground="DarkRed" FontFamily="{StaticResource FaFreeSolid}" FontSize="30" VerticalAlignment="Center" Margin="15,0,0,0"/>
                            <TextBlock Text="{TemplateBinding Content}" Foreground="Gainsboro" FontSize="20" TextWrapping="Wrap" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="20,0,0,0"/>
                        </StackPanel>
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter TargetName="GridMouseOver" Property="Visibility" Value="Visible"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

我要解决的下一个问题是创建依赖项 属性 以在基于此样式创建按钮时通过 属性 设置图标图像和图标颜色。