【发布时间】:2022-01-11 01:10:38
【问题描述】:
我为 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>
【问题讨论】:
-
对不起,发布的代码有点乱,需要重新组织。无论如何,默认的
Button控件没有Icon和IconColor属性,因此您必须使用附加属性或扩展标准Button来添加这些属性。此外,用于按钮的模板也可以简化,因为Border可以是直接容器并包括一个水平的StackPanel,它同时承载fa:ImageAwesome和TextBlock(或ContentPresenter)。一旦你实现了Icon和IconColor,那么它们就可以绑定到fa:ImageAwesome(Icon和Foreground)。 -
我是 WPF 和 XAML 的新手,所以我边走边学。实际上,我对您的评论笑得很开心,因为我很高兴它正在发挥作用并且有点自豪。但显然,对于更有经验的程序员来说,这很糟糕。我肯定会在不久的将来尝试实现附加属性,因为我现在知道继续搜索的术语。我已经将边框内容更改为堆栈面板。感谢您的提示。
-
不要误会我的意思,但是干净的代码总是更容易调试并且性能更好。您的代码已经是一个良好的开端并且朝着正确的方向前进 :) 如果您为缺少的属性实现了某些东西(以防接受的答案不符合您的需求)并且仍然需要图标方面的帮助,只需使用您的更改更新您的问题。
标签: c# wpf visual-studio font-awesome