如何通过Behavior和VisualStateManager将TextBox设置为特定的内置VisualState

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何通过Behavior和VisualStateManager将TextBox设置为特定的内置VisualState相关的知识,希望对你有一定的参考价值。

我正在尝试使用验证来显示Windows元素(实际上是文本框)上的验证错误,但是当失败条件发生变化时,我无法获得未集中/未编辑的文本框来更新其验证(均不使用INotifyDataErrorInfoIDataErrorInfo)。

例如,当TextBox1保留特定路径时,TextBox2验证为错误。现在,在更改TextBox2中的路径之后,TextBox1应该会自动清除其错误,但是这没有发生,我总是讨厌输入TextBox并更改其内容以进行验证以进行更新...

因此,我打算使用Behaviors来将它们绑定到Validation布尔值,并使用默认的Validation States(TextBox)使行为将VisualState设置为适当的Valid, InvalidFocused, InvalidUnfocused

这是我的行为(目前仅是PoC,因此没有依赖项属性:]

/// <summary>
/// Behavior for setting the visual style depending on a validation value
/// </summary>
public class TextBoxValidationBindingBehavior : BehaviorBase<TextBox>
{
    /// <summary>
    /// Setup the behavior
    /// </summary>
    protected override void OnAttached()
    {
        base.OnAttached();

        this.AssociatedObject.TextChanged += this.AssociatedObject_TextChanged;
    }

    /// <summary>
    /// Set visual state
    /// </summary>
    private void AssociatedObject_TextChanged(object sender, TextChangedEventArgs e)
    {
        TextBox textBox = this.AssociatedObject as TextBox;

        if (textBox.Text == "Test")
        {
            VisualStateManager.GoToState(textBox, "Valid", false);
        }
        else
        {
            if (textBox.Focus())
            {
                VisualStateManager.GoToState(textBox, "InvalidFocused", true);
            }
            else
            {
                VisualStateManager.GoToState(textBox, "InvalidUnfocused", true);
            }
        }
    }

    /// <summary>
    /// Clean-up the behavior
    /// </summary>
    protected override void OnCleanup()
    {
        this.AssociatedObject.TextChanged -= this.AssociatedObject_TextChanged;

        base.OnCleanup();
    }
}

和文本框定义:

<TextBox   Grid.Row                 = "0" 
           Grid.Column              = "1"
           Margin                   = "0, 2, 0, 2"
           VerticalAlignment        = "Stretch"
           VerticalContentAlignment = "Center"
           Text                     = "{Binding NewBookName}">

    <b:Interaction.Behaviors>
        <behavior:TextBoxValidationBindingBehavior />
    </b:Interaction.Behaviors>

</TextBox>

设置断点,我可以看到代码按预期方式被调用。但是VisualStateManager.GoToState对TextBox绝对没有影响!

如果我为文本框定义模板并设置自定义VisualState,则该行为将起作用。但是,重点并不是要重新定义TextBox的视觉状态,而只是通过将Behavior绑定在顶部的验证布尔值和要显示的消息相关联来使用现有状态...

我非常感谢任何提示!!!另外,如果需要,我很乐意提供更多信息。

以上是关于如何通过Behavior和VisualStateManager将TextBox设置为特定的内置VisualState的主要内容,如果未能解决你的问题,请参考以下文章

如何禁用 d3.behavior.zoom 的双击缩放?

yii2 源码分析Behavior类分析

WPF Interaction框架简介——Behavior

使用 AppBarLayout.Behavior.DragCallback 控制折叠工具栏布局的滚动

基于行为树的AI 与 Behavior Designer插件

如何在 Javascript 中实现 Haskell 的 FRP Behavior 类型?