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 の検証は、ことわざにある大きな苦痛です。ひどいものです。

ただし、できることの 1 つは、コントロールのプロパティからバインディング式を取得し、手動で検証を呼び出すことです。それは悪いですが、うまくいきます。

于 2008-09-19T16:50:52.367 に答える
6

ValidationRuleのValidatesOnTargetUpdatedプロパティを見てください。データが最初に読み込まれたときに検証されます。これは、空のフィールドまたは null フィールドをキャッチしようとしている場合に適しています。

次のようにバインディング要素を更新します。

<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

私は同じ問題を経験し、これを解決するための非常に簡単な方法を見つけました。それでおしまい!!オブジェクトのプロパティが変更された (空の文字列に設定された) ため、検証の発火 !

于 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 に答える