65

いくつかのテキストボックスを含む WPF ダイアログがあります。テキストボックスはビジネス オブジェクトにバインドされ、WPF 検証ルールが添付されています。

問題は、ユーザーが実際にテキスト ボックスにデータを入力しなくても、[OK] ボタンをクリックしてダイアログを閉じることができることです。ユーザーがテキストボックスに情報を入力しようとさえしなかったため、検証ルールは起動しません。

検証チェックを強制して、一部の検証ルールが破られているかどうかを判断することは可能ですか?

ユーザーがダイアログを閉じようとしたときにそれを行うことができ、検証ルールが壊れている場合はそれを禁止します。

ありがとうございました。

4

6 に答える 6

75

3.5SP1 / 3.0SP2では、ValidationRuleベースに新しいプロパティ、つまりValidatesOnTargetUpdated="True"も追加されました。これにより、ターゲットコントロールが更新されたときだけでなく、ソースオブジェクトがバインドされるとすぐに検証が呼び出されます。それはあなたが望むものとは正確に一致しないかもしれませんが、最初に修正する必要のあるすべてのものを見るのは悪くありません。

このように動作します:

<TextBox.Text>
    <Binding Path="Amount" StringFormat="C">
        <Binding.ValidationRules>
            <validation:RequiredValidationRule 
                ErrorMessage="The pledge amount is required." 
                ValidatesOnTargetUpdated="True"  />
            <validation:IsNumericValidationRule 
                ErrorMessage="The pledge amount must be numeric." 
                ValidationStep="ConvertedProposedValue" 
                ValidatesOnTargetUpdated="True"  />
        </Binding.ValidationRules>
    </Binding>
</TextBox.Text>
于 2009-03-21T06:49:07.223 に答える
2

「UpdateSource()」または「UpdateTarget()」を呼び出す必要のない別の方法を次に示します。

var binding = thingToValidate.GetBinding(propertyToValidate);
foreach (var rule in binding.ValidationRules)
{
    var value = thingToValidate.GetValue(propertyToValidate);
    var result = rule.Validate(value, CultureInfo.CurrentCulture);
    if (result.IsValid) 
         continue;
    var expr = BindingOperations.GetBindingExpression(thingToValidate, propertyToValidate);
    if (expr == null)  
        continue;
    var validationError = new ValidationError(rule, expr);
    validationError.ErrorContent = result.ErrorContent;
    Validation.MarkInvalid(expr, validationError);
}
于 2016-06-24T23:00:53.160 に答える
0

Robert Macnee によって提案された上記の方法を使用します。例えば:

//force initial validation
foreach (FrameworkElement item in grid1.Children)
{
    if (item is TextBox)
    {
        TextBox txt = item as TextBox;
        txt.GetBindingExpression(TextBox.TextProperty).UpdateSource();
    }
}        

ただし、このコードを実行する前に、バインドされたコントロールが Visibles であることを確認してください。

于 2012-07-25T11:57:12.167 に答える
-3

データ オブジェクトで INotifyPropertychanged を使用する

public class MyObject : INotifyPropertyChanged
{
    string _MyPropertyToBind = string.Empty;
    public string MyPropertyToBind
    {
        get
        {
            return _MyPropertyToBind;
        }
        set
        {
            _MyPropertyToBind = value;
            NotifyPropertyChanged("MyPropertyToBind");
        }
    }

    public void NotifyPropertyChanged(string property)
    {
        if (this.PropertyChanged != null)
        {
            this.PropertyChanged(this, new PropertyChangedEventArgs(property));
        }
    }
    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    #endregion

}

次のコードをコントロールに追加できます

<TextBox Text="{Binding MyPropertyToBind, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" >

テキストボックスは datacontext オブジェクト (この例では MyObjet ) の propertychanged イベントにサブスクライブし、ソース データが更新されたときに発生すると想定します。

コントロールの更新を自動的に強制します

自分自身を UpdateTarget メソッドと呼ぶ必要はありません

于 2010-10-11T21:26:28.337 に答える