2017-08-28 18 views
0

標準ルールに対してテキストボックスの値を検証し、そのうちの2つが最小値と最大値です。問題は、この値を設定可能にする必要があることです(設定ファイルなど)。WPF:検証ルールのDependencyPropertyへのバインド

public class TextBoxWithIntegerValidation : ValidationRule 
    { 
     private Int32RangeChecker _validRange; 

     public Int32RangeChecker ValidRange 
     { 
      get { return _validRange; } 
      set { _validRange = value; } 
     } 

     public override ValidationResult Validate(object value, CultureInfo cultureInfo) 
     { 
      var str = value as string; 
      if (str == null) 
      { 
       return new ValidationResult(false, Resources.TextResources.TextBoxIsEmpty_ErrorMessage); 
      } 

      int intValue = -1; 
      if (!int.TryParse(str, out intValue)) 
      { 
       return new ValidationResult(false, Resources.TextResources.TextBoxNotIntegerValue_ErrorMessage); 
      } 

      if (intValue < ValidRange.Minimum) 
      { 
       return new ValidationResult(false, 
        string.Format(Resources.TextResources.TextBoxValueLowerThanMin_ErrorMessage, ValidRange.Minimum)); 
      } 

      return new ValidationResult(true, null); 
     } 
    } 

のIntの範囲チェッカー:

public class Int32RangeChecker : DependencyObject 
{ 
    public int Minimum 
    { 
     get { return (int)GetValue(MinimumProperty); } 
     set { SetValue(MinimumProperty, value); } 
    } 

    public static readonly DependencyProperty MinimumProperty = 
     DependencyProperty.Register("Minimum", typeof(int), typeof(Int32RangeChecker), new UIPropertyMetadata(0)); 

    public int Maximum 
    { 
     get { return (int)GetValue(MaximumProperty); } 
     set { SetValue(MaximumProperty, value); } 
    } 

    public static readonly DependencyProperty MaximumProperty = 
     DependencyProperty.Register("Maximum", typeof(int), typeof(Int32RangeChecker), new UIPropertyMetadata(100)); 

} 

し、テキストボックスの検証:よびUserCの内側に配置

<TextBox> 
<TextBox.Text> 
    <Binding Path="Interval" UpdateSourceTrigger="PropertyChanged" ValidatesOnNotifyDataErrors="True"> 
     <Binding.ValidationRules> 
      <validationRules:TextBoxWithIntegerValidation> 
       <validationRules:TextBoxWithIntegerValidation.ValidRange> 
        <validationRules:Int32RangeChecker 
          Minimum="{Binding IntervalMinValue}" 
         /> 
       </validationRules:TextBoxWithIntegerValidation.ValidRange> 
      </validationRules:TextBoxWithIntegerValidation> 
     </Binding.ValidationRules> 
    </Binding> 
</TextBox.Text> 

のTextBox

私は、検証ルールを持っています制御DataContext内に配置された適切なViemModel。

問題は、プロパティIntervalMinValueが検証ルールにバインドされていないことです。私が手動で設定した場合、正常に動作しますが、バインディングでは動作しません。

+0

あなたは、設定 'Min'と' Max'が必要な場合は、それらのビューモデルのプロパティにするだけでなく、 「価値」。 – Dennis

+0

はい、それらはVM内にあります。しかし、VMのプロパティを検証最小値、最大値DPにバインドすることはできません。 – Alex

答えて

3

問題は、Int32RangeCheckerオブジェクトが、ビジュアルツリーの一部ではないオブジェクトに関連付けられているため、ビューモデルにアクセスできないという問題です。あなたは、出力ウィンドウを見るとこのエラーが表示されます...

System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=IntervalMinValue; DataItem=null; target element is 'Int32RangeChecker' (HashCode=32972388); target property is 'Minimum' (type 'Int32') 

この問題を解決するには、ビジュアルツリーの要素に最小プロパティの結合を接続する必要があります。これを行う1つの方法は、目に見えないダミーの要素を追加し、その上にデータコンテキストにバインドすることです...

<FrameworkElement x:Name="dummyElement" Visibility="Hidden"/> 
    <TextBox> 
     <TextBox.Text> 
      <Binding Path="Interval" UpdateSourceTrigger="PropertyChanged" ValidatesOnNotifyDataErrors="True"> 
       <Binding.ValidationRules> 
        <local:TextBoxWithIntegerValidation> 
         <local:TextBoxWithIntegerValidation.ValidRange> 
          <local:Int32RangeChecker 
         Minimum="{Binding Source={x:Reference dummyElement}, Path=DataContext.IntervalMinValue}" 
        /> 
         </local:TextBoxWithIntegerValidation.ValidRange> 
        </local:TextBoxWithIntegerValidation> 
       </Binding.ValidationRules> 
      </Binding> 
     </TextBox.Text> 
    </TextBox> 
+0

どうもありがとう。その周りを踊る数時間を費やし、ついに! – Alex

関連する問題