WPF TextBox验证样式当鼠标结束或具有焦点时消失

时间:2010-10-05 22:38:58

标签: wpf validation custom-controls

我正在创建一个自定义文本框控件,以具有一些默认格式和验证功能,包括接受Action或自定义函数的自定义验证属性。

在我目前的情况下,我不能使用某些人发布的属性验证框架,因为我没有完全修改数据模型对象的权限。我也不能使用ValidationRules,因为并非所有需要这些验证的文本框都会被绑定。

我在静态构造函数中使用了通用文本框样式而不是定义我自己的样式,但我添加了一些数据触发器来根据我的自定义IsValid依赖项属性设置边框和工具提示。

一切似乎都运行良好,但问题是当我鼠标悬停或点击验证失败的文本框时,“无效”样式消失,并且它将转到默认的文本框样式。

我试图为IsMouseOver,IsFocused和IsMouseCaptured事件创建一些额外的数据触发器(如下所示)无济于事。

我错过了什么吗?

静态构造函数(显示我正在使用TextBox样式:

    static ValidatorTextBox()
    {
        //Commenting this line out to use the default textbox style
        DefaultStyleKeyProperty.OverrideMetadata(typeof(ValidatorTextBox), new FrameworkPropertyMetadata(typeof(TextBox)));
    }

这是我的风格:

 <Style TargetType="{x:Type local:ValidatorTextBox}">
    <Style.Triggers>
        <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsValid}" Value="False">
            <Setter Property="BorderBrush" Value="Red" />
            <Setter Property="BorderThickness" Value="1" />
        </DataTrigger>
        <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsRequired}" Value="True">
            <Setter Property="Background" Value="AliceBlue" />
        </DataTrigger>
        <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsFocused}" Value="True">
            <Setter Property="BorderBrush" Value="{Binding RelativeSource={RelativeSource Self}, Path=BorderBrush}" />
        </DataTrigger>
        <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsMouseOver}" Value="True">
            <Setter Property="BorderBrush" Value="{Binding RelativeSource={RelativeSource Self}, Path=BorderBrush}" />
        </DataTrigger>
        <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsMouseCaptured}" Value="True">
            <Setter Property="BorderBrush" Value="{Binding RelativeSource={RelativeSource Self}, Path=BorderBrush}" />
        </DataTrigger>
    </Style.Triggers>
</Style>

1 个答案:

答案 0 :(得分:2)

问题很可能是由默认的TextBox模板引起的。在Aero中(我认为在其他一些主题中也是如此)边框实际上是一个chrome控件,在鼠标悬停时更改为特定颜色。由于这发生在ControlTemplate中,它会覆盖通常用于拉入控件样式上的BorderBrush集的TemplateBinding。最直接的解决方法是将默认的ControlTemplate实际复制到自定义控件的默认样式中,并使用带有自定义触发器的简单边框而不是仅包含样式。

<Style TargetType="{x:Type local:ValidatorTextBox}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:ValidatorTextBox}">
                <Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="true" >
                    <ScrollViewer x:Name="PART_ContentHost" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsValid" Value="False">
                        <Setter Property="Background" TargetName="Bd" Value="Red"/>
                    </Trigger>
                    <Trigger Property="IsEnabled" Value="false">
                        <Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
                        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>