【问题标题】:How to change font icon of ToggleButton with VisualState in Template?如何在模板中使用 VisualState 更改 ToggleButton 的字体图标?
【发布时间】: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="&amp;#xE762;")?

【问题讨论】:

    标签: uwp uwp-xaml controltemplate


    【解决方案1】:

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

    首先,您需要为数据绑定创建一个值转换器,它可以将布尔值转换为 Segoe MDL2 资产图标。

    像这样:

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

    更新

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

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

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

     <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中显示的图标。

    【讨论】:

    • 也就是说我们不能在VisualState的XAML中直接设置字符码?使用 Setter,然后使用 Value="" 或类似的东西设置 Content 属性。我试过了,报错
    • @quangkid 好吧,我建议使用数据绑定的原因是以后更容易更改图标值。如果您需要使用 VisualState,也可以这样做。请检查更新。
    猜你喜欢
    • 1970-01-01
    • 2011-03-04
    • 2021-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多