16

我正在尝试针对对象验证 WPF 表单。当我在文本框中输入内容时,验证会触发失去焦点回到文本框,然后擦除我写的任何内容。但是,如果我只是加载 WPF 应用程序并在文本框上制表符而不从文本框中写入和擦除任何内容,那么它不会被触发。

这是 Customer.cs 类:

public class Customer : IDataErrorInfo
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }

        public string Error
        {
            get { throw new NotImplementedException(); }
        }
        public string this[string columnName]
        {
            get
            {
                string result = null;

                if (columnName.Equals("FirstName"))
                {
                    if (String.IsNullOrEmpty(FirstName))
                    {
                        result = "FirstName cannot be null or empty"; 
                    }
                }
                else if (columnName.Equals("LastName"))
                {
                    if (String.IsNullOrEmpty(LastName))
                    {
                        result = "LastName cannot be null or empty"; 
                    }
                }
                return result;
            }
        }
    }

这是 WPF 代码:

<TextBlock Grid.Row="1" Margin="10" Grid.Column="0">LastName</TextBlock>
<TextBox Style="{StaticResource textBoxStyle}" Name="txtLastName" Margin="10"
         VerticalAlignment="Top" Grid.Row="1" Grid.Column="1">
    <Binding Source="{StaticResource CustomerKey}" Path="LastName"
             ValidatesOnExceptions="True" ValidatesOnDataErrors="True"
             UpdateSourceTrigger="LostFocus"/>         
</TextBox>
4

6 回答 6

20

如果您不反对在代码中添加一些逻辑,则可以使用以下方式处理实际的LostFocus事件:

.xaml

<TextBox LostFocus="TextBox_LostFocus" ....

.xaml.cs

private void TextBox_LostFocus(object sender, RoutedEventArgs e)
{
     ((Control)sender).GetBindingExpression(TextBox.TextProperty).UpdateSource();
}
于 2009-08-28T14:33:23.617 回答
12

不幸的是,这是设计使然。WPF 验证仅在控件中的值发生更改时触发。

难以置信,但却是真实的。到目前为止,WPF 验证是众所周知的最大痛苦——太可怕了。

但是,您可以做的一件事是从控件的属性中获取绑定表达式并手动调用验证。这很糟糕,但它有效。

于 2008-09-19T16:50:52.367 回答
6

查看 ValidationRule 的ValidatesOnTargetUpdated属性。它将在首次加载数据时进行验证。如果您尝试捕获空字段或空字段,这很好。

你会像这样更新你的绑定元素:

<Binding 
    Source="{StaticResource CustomerKey}" 
    Path="LastName" 
    ValidatesOnExceptions="True" 
    ValidatesOnDataErrors="True" 
    UpdateSourceTrigger="LostFocus">
    <Binding.ValidationRules>
        <DataErrorValidationRule
            ValidatesOnTargetUpdated="True" />
    </Binding.ValidationRules>
</Binding>
于 2009-05-27T06:42:07.350 回答
1

我发现处理这个问题的最佳方法是在文本框的 LostFocus 事件上我做了这样的事情

    private void dbaseNameTextBox_LostFocus(object sender, RoutedEventArgs e)
    {
        if (string.IsNullOrWhiteSpace(dbaseNameTextBox.Text))
        {
            dbaseNameTextBox.Text = string.Empty;
        }
    }

然后它看到一个错误

于 2011-12-16T01:27:37.157 回答
0

我遇到了同样的问题,并找到了一种非常简单的方法来解决这个问题:在窗口的 Loaded 事件中,只需输入 txtLastName.Text = String.Empty。就是这样!!由于您的对象的属性已更改(已设置为空字符串),验证的触发!

于 2009-04-04T14:47:13.290 回答
0

以下代码循环遍历所有控件并验证它们。不一定是首选方式,但似乎有效。它仅适用于 TextBlocks 和 TextBoxes,但您可以轻松更改它。

public static class PreValidation
{

    public static IEnumerable<T> FindVisualChildren<T>(DependencyObject depObj) where T : DependencyObject
    {
        if (depObj != null)
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
            {
                DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
                if (child != null && child is T)
                {
                    yield return (T)child;
                }

                foreach (T childOfChild in FindVisualChildren<T>(child))
                {
                    yield return childOfChild;
                }
            }
        }
    }


    public static void Validate(DependencyObject depObj)
    {
        foreach(var c in FindVisualChildren<FrameworkElement>(depObj))
        {
            DependencyProperty p = null;

            if (c is TextBlock)
                p = TextBlock.TextProperty;
            else if (c is TextBox)
                p = TextBox.TextProperty;

            if (p != null && c.GetBindingExpression(p) != null) c.GetBindingExpression(p).UpdateSource();
        }

    }
}

只需在您的窗口或控件上调用 Validate,它就会为您预先验证它们。

于 2011-04-15T04:43:11.977 回答