2

2つのTextBoxコントロール(次のように)があり、現在の値1ではなく、最初のTextBox[]のTextを2番目のTextBox[ ]x:Name="defPointFrom1Txt"のValidationRule[ ]に渡したいと考えています。最初のTextBoxの値が変更されたときのイベントに基づく検証ルールと設定。ただし、XAMLでこれを実行して、すべての検証ロジックを1か所に保持する方法はありますか? MinIntegerValidationRulex:Name="defPointTo1Txt"

            <TextBox x:Name="defPointFrom1Txt" Grid.Row="2" Grid.Column="1" Style="{StaticResource lsDefTextBox}" 
                     Text="{Binding Path=OffensePointsAllowed[0].From}" IsEnabled="False"/>
            <TextBox x:Name="defPointTo1Txt" Grid.Row="2" Grid.Column="2" Style="{StaticResource lsDefTextBox}"
                     LostFocus="defPointTo1Txt_LostFocus">
                <TextBox.Text>
                    <Binding Path="OffensePointsAllowed[0].To" StringFormat="N1">
                        <Binding.ValidationRules>
                            <gui:MinIntegerValidationRule Min="1"/>
                        </Binding.ValidationRules>
                    </Binding>
                </TextBox.Text>
            </TextBox>

完全を期すために、私の検証ルールコードを以下に示します。

  public class IntegerValidationRule : ValidationRule
{

    public override ValidationResult Validate(object value, CultureInfo cultureInfo)
    {
        float controlValue;
        try
        {
            controlValue = int.Parse(value.ToString());
        }
        catch (FormatException)
        {
            return new ValidationResult(false, "Value is not a valid integer.");
        }
        catch (OverflowException)
        {
            return new ValidationResult(false, "Value is too large or small.");
        }
        catch (ArgumentNullException)
        {
            return new ValidationResult(false, "Must contain a value.");
        }
        catch (Exception e)
        {
            return new ValidationResult(false, string.Format("{0}", e.Message));
        }
        return ValidationResult.ValidResult;
    }

}

public class MinIntegerValidationRule : IntegerValidationRule
{
    public int Min { get; set; }

    public override ValidationResult Validate(object value, CultureInfo cultureInfo)
    {

        ValidationResult retValue = base.Validate(value, cultureInfo);
        if (retValue != ValidationResult.ValidResult)
        {
            return retValue;
        }
        else
        {
            float controlValue = int.Parse(value.ToString());
            if (controlValue < Min)
            {
                return new ValidationResult(false, string.Format("Please enter a number greater than or equal to {0}.",Min)); 
            }
            else
            {
                return ValidationResult.ValidResult;
            }
        }
    }
}

アップデート:

以下の回答に応えて、私はDependencyObjectを作成しようとしています。私はそれを次のように行いましたが、ValidationRuleコードでそれを使用する方法がわかりません(または正しく作成したことさえわかりません)。

public abstract class MinDependencyObject : DependencyObject
{
    public static readonly DependencyProperty MinProperty =
      DependencyProperty.RegisterAttached(
      "Min", typeof(int), 
      typeof(MinIntegerValidationRule),
      new PropertyMetadata(), 
      new ValidateValueCallback(ValidateInt)
      );

    public int Min
    {
        get { return (int)GetValue(MinProperty); }
        set { SetValue(MinProperty, value); }
    }
    private static bool ValidateInt(object value)
    {
        int test;
        return (int.TryParse(value.ToString(),out test));
    }
}
4

3 に答える 3

1

Min プロパティは依存関係プロパティではないため、バインドを設定できません。私が以前行っていたのは、ビューモデルに検証プロパティ属性を作成して、クラス インスタンス オブジェクトを提供し、それに基づいて検証を実行することでした。

あなたの場合、依存オブジェクトとして Min を作成します。

于 2013-03-18T15:08:42.313 に答える
0

この投稿「WPFの論理ツリーへの仮想ブランチの接続」JoshSmith 著、2007年5月6日、この問題の解決策の概要を説明します。

于 2013-03-18T19:28:35.680 に答える
0

考えてみればBinding、検証クラスはすでに別のクラスから継承しているため、それを使用するには比較的大きなオーバーヘッドを実装する必要があります。問題はBinding、バインディング ターゲットを(ここでDependencyProperty読むことができるように) にする必要があることです。これは、検証クラスに直接実装することはできません。

たとえば、AttachedProperty検証クラス用に を作成して、 を使用できるようにすることができますBindingここでいくつかの情報を見つけることができます。

于 2013-03-18T15:11:25.167 に答える