属性值的校对:
属性值的校对主要包扩三个方面。首先,需要保证用户输入的值类型正确。其次,也是比较常用的,判断输入值后是否超出规定的范围。最后,在一些情况下,要求数据具有指定的格式,例如小数点后精确到几位的浮点数等。第一个问题,值的类型在用户输入的时候,控件本身就提供了很好的类型判断,所以,一般情况下不需要程序员进行判断。而后两个问题,控件提供的支持就非常有限了,需要程序员针对具体需求进行具体设计。
最近一直在使用Attribute类,所以一上来先想去找一个校对用的属性。很可惜,没有找到。于是考虑其他方法,由于是由控件接收用户输入,所以首先想到了事件响应。也就是在用户改变了属性的取值时触发事件,并根据需求对属性值进行处理。实践证明确实可行。然而项目中的类别众多,其属性也多寡不一,属性的总数就会很大。如果全部用事件响应来处理,就需要对每个类别的每个属性进行判别区分。如果再牵扯上本地化的问题,就更加复杂(因为笔者是通过发生改变的值对应lable的字符串辨别该值是什么属性的,而本地化后该值存在多种可能。。。)。
另外还有一种简单的方法就是在get/set方法里加入if判断。这样控件会自动根据其范围作出反应。同样,该方法存在缺点。就是它不能易根据模式改变判定范围。同时,无法有效格式化数据(因为0.00会被自动转换回0)。
后来,无意在网上看到一段代码。通过自定义Attribute类实现了较对。可惜没有具体实现,判定后的操作怎么实现想不通。例如,发现至超出范围后,怎么将之更新回原先的取值。
这里针对前两种方法以代码示例:(通过自定义属性类实现的方法稍后更新)
{
...
private void propertyGrid1_PropertyValueChanged(object s, PropertyValueChangedEventArgs e)//事件响应
{
propertyGrid1.SelectedObject = ins1;
propertyGrid1.Update();
propertyGrid1.Refresh();
if (e.ChangedItem.Label == "A" && !IsIntValid((int)e.ChangedItem.Value) ) //如果校对发现对应数据不合格
{
TClass1 tc1 = (TClass1)((PropertyGrid)s).SelectedObject;
e.ChangedItem.PropertyDescriptor.SetValue(
propertyGrid1.SelectedObject, (int)e.OldValue);
MessageBox.Show("Wrong", "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
}
private static bool IsIntValid( int i)
{
return ((i>= 0) && (i<= 100));
}
...
}
public class Test
{
private int i;
...
public int I//属性体内判断
{
get{return I;}
set{if((value>=0)&&(value<=100))i = value;}
}
}