我在WPF MVVM应用程序上使用IDataErrorInfo验证数据时遇到WEIRD问题,我正在做的是:
要验证的属性
public Decimal GlassPrice
{
get
{
return _GlassPrice;
}
set
{
if (_GlassPrice != value)
{
_GlassPrice = value;
OnPropertyChanged("GlassPrice");
CarName = allPropertiesValid.ToString();
}
}
}
“我将在上面的”Set“函数CarName = .. etc中解释最后一行” 然后,一个bool变量,默认值为false,表示所有要验证的属性是否为真,在canExecute函数中使用。
public bool allPropertiesValid
{
get { return _allPropertiesValid; }
set
{
if (_allPropertiesValid != value)
{
_allPropertiesValid = value;
OnPropertyChanged("allPropertiesValid");
}
}
}
然后是一个字典,用于保存具有bool值的属性名称对,如下所示
validAllProperties = new Dictionary<string, bool>();
validAllProperties.Add("GlassPrice", false);
然后,当然是一种验证属性的方法如下
private string validateGlassPrice()
{
if (GlassPrice <= 0)
{
return "price can't be 0 nor a minus value ";
}
else
{
return String.Empty;
}
}
然后在IDataErrorInfo实现
string IDataErrorInfo.this[string columnName]
{
get
{
string error = String.Empty;
switch (columnName)
{
case "GlassPrice":
error = validateGlassPrice();
validAllProperties["GlassPrice"] = String.IsNullOrEmpty(error) ? true : false;
validateAllProperties();
return error;
default:
throw new ApplicationException("Wrong Property name being validated");
}
}
}
最后设置“allPropertiesValid”的最终值的方法取决于字典中的bool值
private void validateAllProperties()
{
foreach (bool isValid in validAllProperties.Values)
{
if (isValid == false)
{
allPropertiesValid = false;
return;
}
}
allPropertiesValid = true;
}
CarName我说我稍后会解释是绑定到textBox的属性,我现在用它来跟踪运行时的“allPropertiesValid”值,所以我让canExecute方法返回“allPropertiesValid”并依赖于与命令关联的按钮将被启用/禁用,这个场景工作正常,我已经使用它完成了3或4个表单并且它们完美地工作,但是在这个特定的一个它没有,在修改之后,事实证明问题只出现在这个特定的属性“GlassPrice”上,我禁用了其他属性的所有验证,并且只是将其保留在此,现在发生的是:当输入1作为值时,Carname给我假,但按钮现在已启用? ?只要CanExecute方法的值为false,就不应该启用该按钮,然后我将0添加为1并且它们变为10然后它变为True,并且无论textBox中的值是否发生变化都保持为True,即使我输入了无效数据如0或null它仍然是真的,按钮总是启用??我坐了几个小时试图解决这个问题,我希望有人可以帮助我
提前致谢
编辑: 那么问题是:如何在TextBox为空时检查Decimal ??,GlassPrice为Decimal且Decimal不接受空值,以下方法检查GlassPrice是否为0或者否,但不是null或空白
private string validateGlassPrice()
{
if (GlassPrice <= 0)
{
return "price can't be 0 nor a minus value ";
}
else
{
return String.Empty;
}
}
答案 0 :(得分:1)
我发布的内容中看不出任何明显错误的内容。以下是一些可以帮助您找到问题的建议:
首先,您要查看的行为(启用/禁用按钮)取决于正在评估的CanExecute
并返回正确的值。这真的发生了吗?找出答案的一个好方法是使用CanExecute
方法将消息写入控制台,例如:
Console.WriteLine("CanExecute called; returning " + result);
return result;
然后,您可以在使用程序时将“输出”窗口保留在屏幕上,并查看属性是否正在按预期进行评估,以及在评估属性时是否返回值你期待它。
第二个建议是在视图模型中开始使用字符串常量而不是文字。我没有看到你在这里犯了任何错误,但是你发布的代码在三个不同的地方使用字符串文字"GlassPrice"
。如果其中任何一个拼写错误,您的代码将以您不期望的方式失败。
最后,两个风格问题 - 这些不是问题的根源,但它们会简化您的代码。这样:
validAllProperties["GlassPrice"] = String.IsNullOrEmpty(error) ? true : false;
应该是这样的:
validAllProperties["GlassPrice"] = String.IsNullOrEmpty(error);
和此:
foreach (bool isValid in validAllProperties.Values)
{
if (isValid == false)
{
allPropertiesValid = false;
return;
}
}
allPropertiesValid = true;
可以很容易就是这样:
allPropertiesValid = validAllProperties.Values.All(x => x);