IDataErrorInfo 的索引器在向 (int)-Textbox 发送短信时不会引发
Indexer of IDataErrorInfo doesn't raise while texting to an (int)-Textbox
我无法检查用户是否将一些文本设置到绑定到整数值的文本框中。如果用户设置数字一切正常。如果是负数,文本框外会出现红色边框,并且 OK 按钮会变灰。如果他在文本框中设置文本,文本框也是红色的,但确定按钮不会变灰。
我得到了以下文本框和按钮
<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}" />
我的模型如下:
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();
}
}
在基本模型中,我包括了 IDataErrorInfo 和 INotifyPropertyChanged。我获得了以下用于索引器调用的方法,但索引器调用不会在文本输入时引发...
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();
}
我希望当用户将文本输入文本框时按钮变灰。
所以,我终于找到了解决方案...我将 Length-type 更改为字符串并使用正则表达式解决了它。
对象模型:
[RegularExpression("([1-9][0-9]*)", ErrorMessage = "Must be a positive number")]
public string Length { get; set; }
基本模型的新 CollectErrors() 方法:
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();
}
我无法检查用户是否将一些文本设置到绑定到整数值的文本框中。如果用户设置数字一切正常。如果是负数,文本框外会出现红色边框,并且 OK 按钮会变灰。如果他在文本框中设置文本,文本框也是红色的,但确定按钮不会变灰。
我得到了以下文本框和按钮
<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}" />
我的模型如下:
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();
}
}
在基本模型中,我包括了 IDataErrorInfo 和 INotifyPropertyChanged。我获得了以下用于索引器调用的方法,但索引器调用不会在文本输入时引发...
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();
}
我希望当用户将文本输入文本框时按钮变灰。
所以,我终于找到了解决方案...我将 Length-type 更改为字符串并使用正则表达式解决了它。
对象模型:
[RegularExpression("([1-9][0-9]*)", ErrorMessage = "Must be a positive number")]
public string Length { get; set; }
基本模型的新 CollectErrors() 方法:
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();
}