WPF 유효성 검사 오류 감지


Answers

다음 코드 (Chris Sell & Ian Griffiths의 WPF Programming WPF 책자)는 종속성 개체와 그 자식에 대한 모든 바인딩 규칙의 유효성을 검사합니다.

public static class Validator
{

    public static bool IsValid(DependencyObject parent)
    {
        // Validate all the bindings on the parent
        bool valid = true;
        LocalValueEnumerator localValues = parent.GetLocalValueEnumerator();
        while (localValues.MoveNext())
        {
            LocalValueEntry entry = localValues.Current;
            if (BindingOperations.IsDataBound(parent, entry.Property))
            {
                Binding binding = BindingOperations.GetBinding(parent, entry.Property);
                foreach (ValidationRule rule in binding.ValidationRules)
                {
                    ValidationResult result = rule.Validate(parent.GetValue(entry.Property), null);
                    if (!result.IsValid)
                    {
                        BindingExpression expression = BindingOperations.GetBindingExpression(parent, entry.Property);
                        System.Windows.Controls.Validation.MarkInvalid(expression, new ValidationError(rule, expression, result.ErrorContent, null));
                        valid = false;
                    }
                }
            }
        }

        // Validate all the bindings on the children
        for (int i = 0; i != VisualTreeHelper.GetChildrenCount(parent); ++i)
        {
            DependencyObject child = VisualTreeHelper.GetChild(parent, i);
            if (!IsValid(child)) { valid = false; }
        }

        return valid;
    }

}

귀하의 페이지 / 창에서 저장 버튼 클릭 이벤트 처리기에서 이것을 호출 할 수 있습니다

private void saveButton_Click(object sender, RoutedEventArgs e)
{

  if (Validator.IsValid(this)) // is valid
   {

    ....
   }
}
Question

WPF에서는 ExceptionValidationRule 또는 DataErrorValidationRule 사용하여 데이터 바인딩 중에 데이터 레이어에서 발생하는 오류를 기반으로 유효성 검사를 설정할 수 있습니다.

이 방법으로 여러 개의 컨트롤을 설정하고 저장 버튼이 있다고 가정합니다. 사용자가 저장 버튼을 클릭하면 저장을 진행하기 전에 유효성 검사 오류가 없는지 확인해야합니다. 유효성 검사 오류가있는 경우, 당신은 그들에게 소리 치고 싶다.

WPF에서 데이터 바인딩 된 컨트롤에 유효성 검사 오류가 설정되어 있는지 어떻게 확인할 수 있습니까?




모든 컨트롤 트리를 반복적으로 반복하고 연결된 속성 Validation.HasErrorProperty를 확인한 다음 처음에 찾은 항목에 집중합니다.

이미 작성된 많은 솔루션을 사용할 수도 있습니다. 예제 및 추가 정보를 보려면 this 스레드를 확인할 수 있습니다.




나는 작은 최적화를 제공 할 것이다.

동일한 컨트롤을 여러 번 사용하면 위 코드를 추가하여 실제로 유효성 검사 규칙이있는 컨트롤 목록을 유지할 수 있습니다. 그런 다음 유효성을 검사 할 필요가있을 때마다 전체 시각적 트리가 아닌 해당 컨트롤로만 이동하십시오. 당신이 그러한 통제를 많이한다면 훨씬 더 나아질 것입니다.




동일한 문제가 발생하여 제공된 솔루션을 사용해 보았습니다. H-Man2와 skiba_k의 솔루션의 조합은 나를 제외하고는 거의 정상적으로 작동했습니다. My Window에는 TabControl이 있습니다. 유효성 검사 규칙은 현재 보이는 TabItem에 대해서만 평가됩니다. 그래서 LogicalTreeHelper로 VisualTreeHelper를 대체했습니다. 이제 작동합니다.

    public static bool IsValid(DependencyObject parent)
    {
        // Validate all the bindings on the parent
        bool valid = true;
        LocalValueEnumerator localValues = parent.GetLocalValueEnumerator();
        while (localValues.MoveNext())
        {
            LocalValueEntry entry = localValues.Current;
            if (BindingOperations.IsDataBound(parent, entry.Property))
            {
                Binding binding = BindingOperations.GetBinding(parent, entry.Property);
                if (binding.ValidationRules.Count > 0)
                {
                    BindingExpression expression = BindingOperations.GetBindingExpression(parent, entry.Property);
                    expression.UpdateSource();

                    if (expression.HasError)
                    {
                        valid = false;
                    }
                }
            }
        }

        // Validate all the bindings on the children
        System.Collections.IEnumerable children = LogicalTreeHelper.GetChildren(parent);
        foreach (object obj in children)
        {
            if (obj is DependencyObject)
            {
                DependencyObject child = (DependencyObject)obj;
                if (!IsValid(child)) { valid = false; }
            }
        }
        return valid;
    }



답변 형식 아간에서는 명시 적으로 유효성 검사 규칙을 반복하는 대신 expression.UpdateSource(): 호출 expression.UpdateSource(): 것이 좋습니다 expression.UpdateSource():

if (BindingOperations.IsDataBound(parent, entry.Property))
{
    Binding binding = BindingOperations.GetBinding(parent, entry.Property);
    if (binding.ValidationRules.Count > 0)
    {
        BindingExpression expression 
            = BindingOperations.GetBindingExpression(parent, entry.Property);
        expression.UpdateSource();

        if (expression.HasError) valid = false;
    }
}



Links