1

特定のコントロール (このシナリオでは TextBox) の検証規則を作成しようとしています。

ValidationRule と DepedencyProperty を利用する適切な手順を実行しましたが、オブジェクトのプロパティへの正常な Binding を取得できません。

以下のコードを見つけてください。補足として、カスタム Validation クラスの「Is Required」は、XAML で明示的に値を設定しない限り、常に False です (「Is Ranged」パラメーターに従ってバインドなし)。

ヒントや提案をいただければ幸いです。

前もって感謝します :)

XAML コード:

<TextBox Style="{StaticResource ValidationError}" LostFocus="ForceValidationCheck"
         Visibility="{Binding Type, Converter={StaticResource Visibility}, ConverterParameter='Number'}"
         IsEnabled="{Binding RelativeSource={x:Static RelativeSource.Self}, Converter={StaticResource IsEnabled}}">
    <TextBox.Text>
        <Binding Path="Value">
            <Binding.ValidationRules>
                <validation:NumericValidation>
                    <validation:NumericValidation.Dependency>
                        <validation:NumericDependency IsRequired="{Binding Path=IsRequired}" IsRanged="True" Min="5"/>
                    </validation:NumericValidation.Dependency>
                </validation:NumericValidation>
            </Binding.ValidationRules>
        </Binding>
    </TextBox.Text>
</TextBox>

検証クラス:

public NumericDependency Dependency { get; set; }

public override ValidationResult Validate(object value, CultureInfo cultureInfo)
{
    isRequired = Dependency.IsRequired;
}

検証依存クラス:

public static readonly DependencyProperty IsRequiredProperty =
        DependencyProperty.Register("IsRequired", typeof(bool), typeof(NumericDependency), new UIPropertyMetadata(default(bool)));

public bool IsRequired
{
    get
    {
        return (bool) GetValue(IsRequiredProperty);
    }
    set
    {
        SetValue(IsRequiredProperty, value);
    }
}
4

4 に答える 4

1

"Dependency" オブジェクトは論理ツリーの一部ではないため、IsRequired は常に false です。そのため、ElementName または DataContext を内部データ バインディングのソースとして使用することはできません。

この問題の解決策は、次の Thomas Levesque の記事に基づいています。継承されない/

"Freezable" を継承し、Data 依存関係プロパティを宣言するクラスを作成する必要があります。Freezable クラスの興味深い機能は、ビジュアル ツリーまたは論理ツリーにない場合でも、Freezable オブジェクトが DataContext を継承できることです。

public class BindingProxy : Freezable
{
   #region Overrides of Freezable
   protected override Freezable CreateInstanceCore()
   {
      return new BindingProxy();
   }
   #endregion

   public object Data
   {
      get { return (object)GetValue(DataProperty); }
      set { SetValue(DataProperty, value); }
   }

   // Using a DependencyProperty as the backing store for Data.  This enables animation, styling, binding, etc...
   public static readonly DependencyProperty DataProperty =
      DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy), new UIPropertyMetadata(null));
}

その後、テキスト ボックスのリソースでこのクラスのインスタンスを宣言し、Data プロパティを現在の DataContext にバインドできます。

<TextBox.Resources>
   <local:BindingProxy x:Key="proxy" Data="{Binding}"/>
<TextBox.Resources/>

最後に、この BindingProxy オブジェクトをバインディングのソースとして指定します。

<validation:NumericDependency IsRequired="{Binding Source={StaticResource proxy} Path=Data.IsRequired}" IsRanged="True" Min="5"/>

パスは BindingProxy オブジェクトに相対的であるため、バインディング パスには "Data" をプレフィックスとして付ける必要があることに注意してください。

于 2015-02-06T19:34:07.310 に答える
0

コントロールの検証を実装する別の方法があります。ただし、最初の問題を解決する方法を知りたいので、助けていただければ幸いです。

もう 1 つの方法は、モデルの IDataErrorInfo インターフェイスを実装することです。

例:

public string this[string columnName]
{
    get
    {
        if (string.Equals(columnName, "Value", StringComparison.CurrentCultureIgnoreCase))
        {
            string value = Convert.ToString(Value);

            if (string.IsNullOrEmpty(value) && IsRequired)
            {
                return ValidationMessage.RequiredValue;
            }
        }

        return string.Empty;
    }
}
于 2012-12-06T09:35:16.200 に答える