WPF ItemsControl ItemTemplate検証

data-binding itemscontrol validation wpf
WPF ItemsControl ItemTemplate検証

ItemsControlに検証エラーのある子コントロールがあるかどうかを判断する方法はありますか? この値(ブール値)をButtonのIsEnabledプロパティにバインドしたいと思います。

  1  0


ベストアンサー

私は最近、この前のSO回答_https://stackoverflow.com/questions/127477/detecting-wpf-validation-errors/128346#128346 [WPF検証エラーの検出] _からのコードを使用して、まさにこれに効果を発揮しました。

DataGridを含むユーザーコントロールがあります。 ユーザーコントロールは、ゲッターを含む `IsValid`プロパティを公開します。これは、DependencyObjectとしてDataGridに渡す静的IsValid関数を呼び出すだけです。

public class MyControl : UserControl
{
    public bool IsValid
    {
        get { return Validator.IsValid(MyDataGrid); }
    }
}

コントロールの「IsValid」プロパティは、有効/無効にするボタンにバインドするコマンドのCanExecute関数によって確認できます。

私がリンクしたコードの私の唯一の問題は、バインディングの検証を実際に評価することでした。これは、技術的に無効であるがまだ無効化されていないフィールドを実行するとすぐに(つまり、 ユーザーはまだ取得していないため、そのフィールドにデータを入力していない可能性があります)は無効な状態になります-これを回避または軽減する方法はまだ検討していません。

” ” ‘

編集:

これは、前述したようにコントロールを無効にしない更新バージョンです。 いくつかの行をコメントアウト/わずかに変更しましたが、そこにすべてを残したので、違いがわかります。 最初の無効なバインディングが見つかった瞬間に終了するため、これも高速に実行されることに注意してください。

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;
                    return 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 false;
        }
    }

    //return valid;
    return true;
}

0


なぜか、slugterの答えがうまくいかなかった( LocalValueEnumerator`はいくつかのプロパティを返したが、 Text`のようなバインドされたプロパティは返さなかった)。

このコード(https://stackoverflow.com/a/4650392/28544 [この回答]から派生)で動作するように管理しました:

public static bool IsValid(DependencyObject obj)
{
    // The dependency object is valid if it has no errors,
    //and all of its children (that are dependency objects) are error-free.
    return !Validation.GetHasError(obj) &&
        GetVisualTreeChildren(obj)
        .OfType()
        .All(child => IsValid(child));
}

//VisualTreeHelper don't have a method to get all the children of a visual object
private static IEnumerable GetVisualTreeChildren(DependencyObject parent)
{
    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
        yield return VisualTreeHelper.GetChild(parent, i);
}

0


タイトルとURLをコピーしました