【问题标题】:Set Validation.ErrorTemplate based on control state根据控件状态设置 Validation.ErrorTemplate
【发布时间】:2014-02-05 15:36:12
【问题描述】:

我已经修改了基于 TextBoxBase 的控件的默认 Validation.ErrorTemplate。 这样我就会弹出工具提示和标签,在输入字段获得焦点时显示错误。

当控件没有文本但需要输入时,我想删除默认的红色边框,并将红色边框替换为控件左侧的星 *。

我认为,如果您有很多必填字段,那么使用会遇到一个充满可怕红色框的表单。只有当您输入了无效值(例如年龄等于 223)时,才会显示红色边框。

所以我想我想根据触发器切换模板或部分模板。

【问题讨论】:

    标签: wpf wpf-controls


    【解决方案1】:

    您可以将Binding.ValidatesOnExceptionsBinding.ValidatesOnDataErrors 属性设置为False,以阻止默认的红色Border 显示。您可以使用 Validation.ErrorTemplate 属性应用星号,您似乎已经发现:

    <ControlTemplate x:Key="RedAsteriskValidationTemplate">
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="*" Foreground="Red" FontWeight="Bold" Margin="0,0,5,0" />
            <AdornedElementPlaceholder />
        </StackPanel>
    </ControlTemplate>
    

    您可以在 MSDN 上的 Validation.ErrorTemplate property 页面上找到更多示例,包括使用 Trigger 的示例。

    【讨论】:

    • 当然我可以这样做,但我想用我的验证规则来驱动 UI。我可以为同一个属性设置一个非空规则和一个范围规则。非空应显示星号,范围规则应显示边框和带有错误消息的小弹出窗口。
    【解决方案2】:

    恕我直言,您不能在 TextBox 控件上使用 StyleSelector。这是我的错。相反,您可以使用简单的转换器来切换 TextBox 样式。

    这是示例代码:

    型号:

    public class User : ModelBase
    {
        private string _login;
    
        [Required(ErrorMessage = "Login can not be empty")]
        [MaxLength(20, ErrorMessage = "Login max lenght is 20")]
        public string Login
        {
            get
            {
                return _login;
            }
    
            set
            {
                _login = value;
                OnPropertyChanged("Login");
            }
        }
    }
    

    在 App.xaml 中使用自定义错误模板创建 TextBox 样式。

    App.xaml

    <Application.Resources>
        <Style x:Key="AsteriskErrorStyle"
               TargetType="{x:Type TextBox}">
    
            <Setter Property="Validation.ErrorTemplate">
                <Setter.Value>
                    <ControlTemplate>
                        <StackPanel Orientation="Horizontal">
                            <AdornedElementPlaceholder x:Name="AdornedElementPlaceholder" />
    
                            <TextBlock Foreground="Red"
                                       Margin="10,0,0,0"
                                       VerticalAlignment="Top"
                                       FontSize="20"
                                       Text="*"
                                       ToolTip="{Binding ElementName=AdornedElementPlaceholder,  Path=AdornedElement.(Validation.Errors)[0].ErrorContent}">
                            </TextBlock>
                        </StackPanel>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    
        <Style x:Key="RedBorderErrorStyle"
               TargetType="{x:Type TextBox}">
    
            <Setter Property="Validation.ErrorTemplate">
                <Setter.Value>
                    <ControlTemplate>
                        <Border BorderThickness="1.5"
                                BorderBrush="Red">
                            <AdornedElementPlaceholder x:Name="AdornedElementPlaceholder" />
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Application.Resources>
    

    转换器:

    public class TextBoxStyleConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            string textBoxTex = value.ToString();
    
            var asteriskErrorStyle = Application.Current.FindResource("AsteriskErrorStyle") as Style;
            var redBorderErrorStyle = Application.Current.FindResource("RedBorderErrorStyle") as Style;
    
            if (string.IsNullOrEmpty(textBoxTex))
            {
                return asteriskErrorStyle;
            }
            else
            {
                return redBorderErrorStyle;
            }
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    

    用法:

    <Window.Resources>   
        <styleSelector:TextBoxStyleConverter x:Key="TextBoxStyleConverter"/>
    </Window.Resources>
    
    <TextBox Grid.Column="1"
             Grid.Row="0"
             Margin="5,5,80,5"
             Style="{Binding RelativeSource={RelativeSource Self}, Path=Text,Converter={StaticResource TextBoxStyleConverter}}"
             Text="{Binding Path=User.Login, ValidatesOnNotifyDataErrors=True}" >
    

    您可以下载示例项目here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-18
      • 1970-01-01
      • 2012-03-15
      • 2018-12-09
      • 2013-12-16
      相关资源
      最近更新 更多