Warm tip: This article is reproduced from serverfault.com, please click

uwp-如何使用模板中的 VisualState 更改 ToggleButton 的字体图标?

(uwp - How to change font icon of ToggleButton with VisualState in Template?)

发布于 2020-12-31 03:02:39

我的 XAML 页面中有一个 ToggleButton:

<ToggleButton Content="&#xE762;" IsChecked="True" FontFamily="Segoe MDL2 Assets" />

但是我想在 IsChecked 更改时更改其图标。所以我在 XAML 中创建了一个 ToggleButton 并为它设置了一个模板

<ControlTemplate x:Key="ToggleButtonTemplate2" TargetType="ToggleButton">
   
</ControlTemplate>
...
<ToggleButton Template="{StaticResource ToggleButtonTemplate2}" IsChecked="True" FontFamily="Segoe MDL2 Assets" />

如何使用字体代码设置其图标取决于状态(如Content="&#xE762;")?

Questioner
quangkid
Viewed
0
Roy Li - MSFT 2020-12-31 15:10:33

所以你想根据切换按钮的IsChecked属性更改内容,对吗?如果是这样,你不需要设置模板,你可以使用简单的数据绑定来实现。

首先,你需要为数据绑定创建一个值转换器,它可以将 bool 值转换为 Segoe MDL2 Assets 图标。

像这样:

 public class DateFormatter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        bool ischecked = (bool)value;

        string content =null;

        if (ischecked)
        {
            //the button is checked
            content = "\xE762";
        }
        else 
        {
            //the button is unchecked
            content = "\xE759";
        }

        return content;
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        throw new NotImplementedException();
    }
}

之后,你需要在 xaml 代码中设置绑定。

像这样:

 <Page.Resources>
    
    <local:DateFormatter x:Key="MyValueConverter"/>
    
</Page.Resources>

<Grid>
    <ToggleButton x:Name="MyToggleButton"  Content="{Binding ElementName=MyToggleButton, Path=IsChecked, Mode=OneWay, Converter={StaticResource MyValueConverter}}" IsChecked="True" FontFamily="Segoe MDL2 Assets" />
</Grid>

现在,当你选中或取消选中切换按钮时,图标将根据需要更改。

更多信息请参考:IValueConverter 接口值转换器

更新

我建议使用数据绑定的原因是以后更容易更改图标值。

如果你必须使用visualstate,也可以这样做。你需要先创建 ToggleButton 的默认样式。Document Outline在 VS 中打开窗口,右键单击你添加到 XAML 的 ToggleButton,将鼠标移至Edit a template,然后选择Edit a Copy

然后你可以找到名为Checked, CheckedPointerOver,的视觉状态CheckedPressed对这些状态再添加一项更改,如下所示:

 <VisualState x:Name="Checked">
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Background">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleButtonBackgroundChecked}"/>
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleButtonForegroundChecked}"/>
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="BorderBrush">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleButtonBorderBrushChecked}"/>
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Content">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="&#xE759;"/>
                                        </ObjectAnimationUsingKeyFrames>
                                        <PointerUpThemeAnimation Storyboard.TargetName="ContentPresenter"/>
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="CheckedPointerOver">
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Background">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleButtonBackgroundCheckedPointerOver}"/>
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="BorderBrush">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleButtonBorderBrushCheckedPointerOver}"/>
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleButtonForegroundCheckedPointerOver}"/>
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Content">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="&#xE759;"/>
                                        </ObjectAnimationUsingKeyFrames>
                                        <PointerUpThemeAnimation Storyboard.TargetName="ContentPresenter"/>
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="CheckedPressed">
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Background">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleButtonBackgroundCheckedPressed}"/>
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleButtonForegroundCheckedPressed}"/>
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="BorderBrush">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleButtonBorderBrushCheckedPressed}"/>
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Content">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="&#xE759;"/>
                                        </ObjectAnimationUsingKeyFrames>
                                        <PointerDownThemeAnimation Storyboard.TargetName="ContentPresenter"/>
                                    </Storyboard>
                                </VisualState>

如你所见,我现在添加了这些状态的内容更改,你可以在选中ToggleButton时看到你想要在ToggleButton中显示的图标。