2017-02-15 3 views
0

ユーザーが整数値にバインドされたテキストボックスにテキストを設定したかどうかを確認できません。ユーザーが数字を設定する場合、すべてがOKです。負の数の場合は、テキストボックスの外側に赤い枠線が表示され、OKボタンがグレーアウトします。テキストボックスにテキストを設定する場合は、テキストボックスも赤ですが、OKボタンはグレーアウトしません。IDataErrorInfoのインデクサーが(int)-Textboxにメッセージを出力中に発生しない

enter image description here

私は、次のテキストボックスとボタン

<TextBox Text="{Binding ObjectModel.Length, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" x:Name="textBox_Length" /> 

<Button x:Name="button_applyChanges" Content="Speichern" Command="{Binding ObjectModel.OkCommand}" /> 

を得た私のモデルは以下の通りです:私はIDataErrorInfoとINotifyPropertyChangedのを含めていますbasemodelで

public class ObjectModel : BaseModel 
{ 
    [Required(AllowEmptyStrings = false, ErrorMessage = "{0} can't be empty.")] 
    [Range(typeof(Decimal), "0", "100000000", ErrorMessage = "{0} must be a decimal/number between {1} and {2}.")] 
    public int Length { get; set; } 

    public RelayCommand OkCommand { get; private set; } 

    protected override void InitCommands() 
    { 
     base.InitCommands(); 
     OkCommand = new RelayCommand(
      () => 
      { 
       Trace.WriteLine("OK"); 
      }, 
      () => IsOk); 
    } 

    protected override void OnErrorsCollected() 
    { 
     base.OnErrorsCollected(); 
     OkCommand.RaiseCanExecuteChanged(); 
    } 
} 

。私は、ユーザーがテキストボックスにテキストを入れながら、ボタンがグレー表示にしたい

public virtual string this[string columnName] 
    { 
     get 
     { 
      CollectErrors(); 
      return Errors.ContainsKey(columnName) ? Errors[columnName] : string.Empty; 
     } 
    } 

    private void CollectErrors() 
    { 
     Errors.Clear(); 
     PropertyInfos.ForEach(
      prop => 
      { 
       var currentValue = prop.GetValue(this); 
       var requiredAttr = prop.GetCustomAttribute<RequiredAttribute>(); 
       var maxLenAttr = prop.GetCustomAttribute<MaxLengthAttribute>(); 
       var numericAttr = prop.GetCustomAttribute<RangeAttribute>(); 

       if (requiredAttr != null) 
        if (string.IsNullOrEmpty(currentValue?.ToString() ?? string.Empty)) 
         Errors.Add(prop.Name, requiredAttr.ErrorMessage); 

       if (maxLenAttr != null) 
        if ((currentValue?.ToString() ?? string.Empty).Length > maxLenAttr.Length) 
         Errors.Add(prop.Name, maxLenAttr.ErrorMessage); 

       if (numericAttr != null) 
       { 
        var result = 0; 
        var resultBool = Int32.TryParse(currentValue.ToString(), out result); 

         if(result <= 0 || !resultBool) 
          Errors.Add(prop.Name, numericAttr.ErrorMessage); 
       } 
       // further attributes 
      }); 
     // we have to this because the Dictionary does not implement INotifyPropertyChanged    
     OnPropertyChanged(nameof(HasErrors)); 
     OnPropertyChanged(nameof(IsOk)); 
     // commands do not recognize property changes automatically 
     OnErrorsCollected(); 
    } 

... doesntのは、テキスト入力に引き上げるインデクサ・コールのための次のメソッドを得たが、インデクサ-呼び出します。

+0

'ObjectModel.Length'だから、バインディングは、と呼ばれるテキストボックスのDataContextの内のオブジェクトのプロパティがあります' ObjectModelインスタンスが含まれています。 – Will

+0

UserControlのxamlは次のように記述します: ' ObjectInspector(ViewModel)は、ViewModelLocatorによって初期化されます。 viewmodelはオブジェクト "objectModel"を保持します。 MVVMのために少し複雑です。自分の質問にもっとコードを追加したいのですか? – Chpo7234

答えて

0

私は最終的に解決策を得ました...長さタイプを文字列に変更し、正規表現で解決しました。

ObjectModel:

[RegularExpression("([1-9][0-9]*)", ErrorMessage = "Must be a positive number")] 
    public string Length { get; set; } 

新CollectErrors() - basemodelの方法:

private void CollectErrors() 
    { 
     Errors.Clear(); 
     PropertyInfos.ForEach(
      prop => 
      { 
       var currentValue = prop.GetValue(this); 
       var requiredAttr = prop.GetCustomAttribute<RequiredAttribute>(); 
       var maxLenAttr = prop.GetCustomAttribute<MaxLengthAttribute>(); 
       var regexAttr = prop.GetCustomAttribute<RegularExpressionAttribute>(); 

       if (requiredAttr != null) 
        if (string.IsNullOrEmpty(currentValue?.ToString() ?? string.Empty)) 
         Errors.Add(prop.Name, requiredAttr.ErrorMessage); 

       if (maxLenAttr != null) 
        if ((currentValue?.ToString() ?? string.Empty).Length > maxLenAttr.Length) 
         Errors.Add(prop.Name, maxLenAttr.ErrorMessage); 

       if (regexAttr != null) 
        if (!regexAttr.IsValid((currentValue?.ToString() ?? string.Empty))) 
         Errors.Add(prop.Name, regexAttr.ErrorMessage); 
      }); 
     OnPropertyChanged(nameof(HasErrors)); 
     OnPropertyChanged(nameof(IsOk)); 
     OnErrorsCollected(); 
    } 
関連する問題