【发布时间】:2022-01-14 21:08:43
【问题描述】:
我创建了一个自定义控件 (ToggleIcon) 作为 CheckBox 的替代品,并且需要向其添加 IsChecked 属性,以便可以通过编程方式清除它。我尝试通过使用VisualStateManager.GoToState() 来完成此操作,但尽管执行时没有异常,但它不会改变状态。据我所知,它也总是返回 false。我在这里查看了其他几个问题,都说 VisualStateManager 必须位于 UserControl 的根目录中,但是当我移动它时,控件上没有任何显示。我不知道在哪里放置 VisualState XAML 以使其工作,有人对如何解决这个问题有任何想法吗?或者,是否有另一种方法来实现 IsChecked 并在状态更改时更新状态?我可以在单击/轻按控件时更新 IsChecked 属性,但无法使其反向工作(即当 IsChecked 更改时,VisualState 更改为 Checked 或 Unchecked)。
用户控件 XAML:
<UserControl
x:Class="CustomControlScratchpad.ToggleIcon"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:CustomControlScratchpad"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="128"
d:DesignWidth="128">
<Grid>
<CheckBox Width="32" Height="32">
<CheckBox.Template>
<ControlTemplate TargetType="CheckBox">
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Tapped="Border_Tapped">
<Grid>
<BitmapIcon x:Name="UncheckedState" UriSource="{Binding UncheckedImage }" Opacity="0" ShowAsMonochrome="False" />
<BitmapIcon x:Name="CheckedState" UriSource="{Binding CheckedImage}" Opacity="0" ShowAsMonochrome="False" />
</Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CheckStates">
<VisualState x:Name="Checked">
<Storyboard>
<DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="CheckedState" />
</Storyboard>
</VisualState>
<VisualState x:Name="Unchecked">
<Storyboard>
<DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="UncheckedState" />
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Border>
</ControlTemplate>
</CheckBox.Template>
</CheckBox>
</Grid>
</UserControl>
用户控制代码:
public bool IsChecked
{
get { return (bool)GetValue(IsCheckedProperty); }
set { SetValue(IsCheckedProperty, value); }
}
public static readonly DependencyProperty IsCheckedProperty =
DependencyProperty.Register("IsChecked", typeof(bool), typeof(ToggleIcon), new PropertyMetadata(false));
public ImageSource UncheckedImage
{
get { return (ImageSource)GetValue(UncheckedImageProperty); }
set { SetValue(UncheckedImageProperty, value); }
}
public static readonly DependencyProperty UncheckedImageProperty =
DependencyProperty.Register("UncheckedImage", typeof(ImageSource), typeof(ToggleIcon), new PropertyMetadata(new System.Uri("ms-appx:///Assets/default-unchecked.png")));
public ImageSource CheckedImage
{
get { return (ImageSource)GetValue(CheckedImageProperty); }
set { SetValue(CheckedImageProperty, value); } }
public static readonly DependencyProperty CheckedImageProperty =
DependencyProperty.Register("CheckedImage", typeof(ImageSource), typeof(ToggleIcon), new PropertyMetadata(new System.Uri("ms-appx:///Assets/default-checked.png")));
public ToggleIcon()
{
this.InitializeComponent();
DataContext = this;
}
private void Border_Tapped(object sender, TappedRoutedEventArgs e)
{
IsChecked = !IsChecked;
}
测试按钮事件代码: 为了进行测试,我添加了一个按钮,当 IsChecked 更改时,该按钮可以将 VisualState 从一个切换到另一个。
private void Button_Tapped(object sender, Windows.UI.Xaml.Input.TappedRoutedEventArgs e)
{
//toggleIcon.IsChecked = !toggleIcon.IsChecked;
if (toggleIcon.IsChecked)
VisualStateManager.GoToState(toggleIcon, "Unchecked", false);
else
VisualStateManager.GoToState(toggleIcon, "Checked", false);
}
【问题讨论】:
-
您能尝试从 DoubleAnimation 中删除
Duration="0"吗?我做了一个简单的 VisualState 来测试,代码可以在不添加Duration的情况下运行。 -
这似乎奏效了,虽然我不明白为什么这会是一个问题....谢谢!如果您想将此作为解决方案发布,我会接受它作为正确答案。再次感谢!
-
很高兴听到这个消息!我会发布它作为答案。
标签: c# uwp custom-controls dependency-properties visualstatemanager