未在 WinRT XAML 中设置自定义视觉对象状态
本文关键字:视觉 对象 状态 自定义 设置 WinRT XAML 未在 | 更新日期: 2023-09-27 18:34:54
我正在尝试在 WinRT XAML 中创建自定义文本框。我希望文本框在输入的数据出现错误时突出显示红色。
因此,首先,我修改了TextBox Temple,并添加了一个新的VisualStateGroup(CustomStates - with HasError State(,并且还更改了Focus组:
<Style TargetType="TextBox">
....
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Focused">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderElement" Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0" Value="Blue" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderElement" Storyboard.TargetProperty="BorderThickness">
<DiscreteObjectKeyFrame KeyTime="0" Value="2" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BackgroundElement" Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="Blue" />
</ObjectAnimationUsingKeyFrames>
<DoubleAnimation Storyboard.TargetName="BackgroundElement" Storyboard.TargetProperty="Opacity" Duration="0" To="0.2" />
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="CustomStates">
<VisualState x:Name="HasError">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderElement" Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0" Value="Red" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderElement" Storyboard.TargetProperty="BorderThickness">
<DiscreteObjectKeyFrame KeyTime="0" Value="2" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BackgroundElement" Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="Red" />
</ObjectAnimationUsingKeyFrames>
<DoubleAnimation Storyboard.TargetName="BackgroundElement" Storyboard.TargetProperty="Opacity" Duration="0" To="0.2" />
</Storyboard>
</VisualState>
</VisualStateGroup>
</Style>
因此,现在在 C# 代码中,我创建了一个自定义的 TextBox 类。
我添加了一个依赖项属性调用 HasError,它只是一个布尔值来保存错误状态。当此值更改时,将调用GoToState方法,该方法将状态设置为我的HasError状态。
我添加了一个委托和事件,用于验证是否发生了错误。
最后,我覆盖了OnLostFocus和OnGotFocus方法。OnLostFocus 呼叫我的委托,OnGotFocus 重置错误状态
public class MyTextBox : TextBox
{
public delegate void ValidateTextHandler(object sender, RoutedEventArgs e);
public event ValidateTextHandler ValidateText = delegate { };
public bool HasError
{
get { return (bool)GetValue(HasErrorProperty); }
set { SetValue(HasErrorProperty, value); }
}
public static readonly DependencyProperty HasErrorProperty = DependencyProperty.Register("HasError", typeof(bool), typeof(MyTextBox), new PropertyMetadata(false, HasErrorChangedCallback));
private static void HasErrorChangedCallback(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
MyTextBox textBox = sender as MyTextBox;
textBox.GoToState(true);
}
void GoToState(bool useTransitions)
{
if (HasError)
{
VisualStateManager.GoToState(this, "HasError", useTransitions);
}
}
protected override void OnGotFocus(RoutedEventArgs e)
{
HasError = false;
base.OnGotFocus(e);
}
protected override void OnLostFocus(RoutedEventArgs e)
{
ValidateText(this, e);
base.OnLostFocus(e);
}
}
所以,这是我的文本框。
现在,在应用程序中,我将文本框的实例添加到窗体并订阅 ValidateText 事件,在该事件中,我只是为了测试,我将 HasError 属性设置为 true。
<MyTextBox x:Name="textTest" ValidateText="textTest_ValidateText" />
private void textTest_ValidateText(object sender, RoutedEventArgs e)
{
textTest.HasError = true;
}
所以,现在当我运行它并且焦点从文本框中丢失时,它会突出显示为红色,这正是我想要的。但是,如果我再次选择相同的文本框并再次将焦点移开,则不会应用 HasError 状态,文本框只会在其默认视图中显示。HasError 代码正在运行,所以我不明白为什么红色错误颜色没有显示??!?!
无论如何,有人可以帮忙吗?我希望这一切都有意义。
这是一个使用 WinRT XAML 和 C# 的 Windows 8 应用程序。
不应使用来自不同组的两个状态来对同一属性进行动画处理。在这种情况下,这是行不通的,因为您已经第二次处于 HasError 状态(您永远不会离开该状态(。
一个解决方案是向"CustomStates"组添加一个名为"NoError"的额外状态。
添加视觉元素(例如只有您的状态才会进行动画处理的附加矩形或边框(。然后,您必须从OnGoFocus覆盖触发NoError状态。