繁体   English   中英

启用文本框后如何触发新的验证?

[英]How to trigger a new validation when a textbox gets enabled?

在wpf对话窗口中,我有一个启用和禁用文本框的复选框。 该文本框的ValidatesOnDataErrors设置为True。 如果选中了此复选框,则通过IDataErrorInfo仅检查此文本框的值。

我的问题是,如果用户选中该复选框,则不会对文本框执行任何新的验证,因此,我没有得到这个红色框表示错误。

为了演示,这里是一个小样本:

<Window x:Class="Validation.ValidationWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="ValidationWindow" Height="300" Width="300">
<DockPanel LastChildFill="False">
    <CheckBox DockPanel.Dock="Top" IsChecked="{Binding InputAllowed}">Input allowed</CheckBox>
    <StackPanel DockPanel.Dock="Top" Orientation="Horizontal">
        <Label>InputValue</Label>
        <TextBox Text="{Binding InputValue, ValidatesOnDataErrors=True}" IsEnabled="{Binding InputAllowed}" Width="50"/>
    </StackPanel>
    <StackPanel DockPanel.Dock="Top" Orientation="Horizontal">
        <Label>InputValue2</Label>
        <TextBox Text="{Binding InputValue2, ValidatesOnDataErrors=True}" Width="50"/>
    </StackPanel>
    <Button DockPanel.Dock="Bottom" Click="OnOk">Ok</Button>
</DockPanel>
</Window>

后面的代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace Validation
{
/// <summary>
/// Interaction logic for ValidationWindow.xaml
/// </summary>
public partial class ValidationWindow : Window, IDataErrorInfo
{
    public bool InputAllowed
    {
        get { return (bool)GetValue(InputAllowedProperty); }
        set { SetValue(InputAllowedProperty, value); }
    }
    public static readonly DependencyProperty InputAllowedProperty =
        DependencyProperty.Register("InputAllowed", typeof(bool), typeof(ValidationWindow), new PropertyMetadata(false));

    public int InputValue
    {
        get { return (int)GetValue(InputValueProperty); }
        set { SetValue(InputValueProperty, value); }
    }
    public static readonly DependencyProperty InputValueProperty =
        DependencyProperty.Register("InputValue", typeof(int), typeof(ValidationWindow), new PropertyMetadata(0));

    public int InputValue2
    {
        get { return (int)GetValue(InputValue2Property); }
        set { SetValue(InputValue2Property, value); }
    }
    public static readonly DependencyProperty InputValue2Property =
        DependencyProperty.Register("InputValue2", typeof(int), typeof(ValidationWindow), new PropertyMetadata(0));


    public ValidationWindow()
    {
        InitializeComponent();
        DataContext = this;
    }

    private void OnOk(object sender, RoutedEventArgs e)
    {
        string msg = Error;
        if(!string.IsNullOrEmpty(Error))
        {
            MessageBox.Show(Error);
            return;
        }
        DialogResult = true;
    }

    #region IDataErrorInfo Members

    public string Error
    {
        get { return ((IDataErrorInfo)this)[null]; }
    }

    public string this[string columnName]
    {
        get
        {
            string msg = string.Empty;

            if(string.IsNullOrEmpty(columnName))
            {
                msg += ((IDataErrorInfo)this)["InputValue"];
                msg += ((IDataErrorInfo)this)["InputValue2"];
            }
            else
            {
                switch(columnName)
                {
                case "InputValue":
                    if(InputAllowed)
                    {
                        if(InputValue <= 0)
                        {
                            msg += "InputValue must be greater that 0!";
                        }
                    }
                    break;
                case "InputValue2":
                    if(InputValue2 <= 0)
                    {
                        msg += "InputValue2 must be greater that 0!";
                    }
                    break;
                }
            }

            return msg;
        }
    }

    #endregion

}
}

我们已经使用它来强制以编程方式更改文本之后进行验证,如果您响应复选框事件而调用它,它也将正常工作:

var binding = someTextBox.GetBindingExpression( TextBox.TextProperty );
if( binding == null )
  return;
binding.UpdateSource();

与stijn的解决方案没有实际差异,但由于我们都有些懒惰:

public static class DependencyPropertyExtensions
{
    public static bool UpdateSource(this FrameworkElement source, DependencyProperty property)
    {
        var binding = source.GetBindingExpression(property);
        if (binding != null)
        {
            binding.UpdateSource();
            return true;
        }

        return false;
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM