如何在模板中使用 VisualState 更改 ToggleButton 的字体图标?
How to change font icon of ToggleButton with VisualState in Template?
我的 XAML 页面中有一个 ToggleButton :
<ToggleButton Content="" 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=""
)?
所以你想根据切换按钮的 IsChecked
属性 来改变内容,对吧?如果是这样,你不需要设置模板,你可以使用简单的数据绑定来实现。
首先,您需要为数据绑定创建一个值转换器,它可以将 bool 值转换为 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 Interface and Value Converters
更新
我之所以建议使用数据绑定是因为以后更改图标值更容易。
如果一定要用visualstate,也可以。您需要先创建 ToggleButton 的默认样式。
在VS中打开Document Outline
window,右击你添加到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=""/>
</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=""/>
</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=""/>
</ObjectAnimationUsingKeyFrames>
<PointerDownThemeAnimation Storyboard.TargetName="ContentPresenter"/>
</Storyboard>
</VisualState>
如您所见,我添加了这些状态中的内容更改,现在,您可以在选中togglebutton时看到要在togglebutton中显示的图标。
我的 XAML 页面中有一个 ToggleButton :
<ToggleButton Content="" 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=""
)?
所以你想根据切换按钮的 IsChecked
属性 来改变内容,对吧?如果是这样,你不需要设置模板,你可以使用简单的数据绑定来实现。
首先,您需要为数据绑定创建一个值转换器,它可以将 bool 值转换为 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 Interface and Value Converters
更新
我之所以建议使用数据绑定是因为以后更改图标值更容易。
如果一定要用visualstate,也可以。您需要先创建 ToggleButton 的默认样式。
在VS中打开Document Outline
window,右击你添加到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=""/>
</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=""/>
</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=""/>
</ObjectAnimationUsingKeyFrames>
<PointerDownThemeAnimation Storyboard.TargetName="ContentPresenter"/>
</Storyboard>
</VisualState>
如您所见,我添加了这些状态中的内容更改,现在,您可以在选中togglebutton时看到要在togglebutton中显示的图标。