企业管理软件开发架构之五 自定义控件开发
数据库中设计的表结构,它的定义如下
CREATE TABLE dbo.ADUSER ( RECNUM DECIMAL (28) IDENTITY NOT NULL, USERID NVARCHAR (10) CONSTRAINT DF__ADUSER__USERID__13F1F5EB DEFAULT ('') NOT NULL, USER_NAME NVARCHAR (50) CONSTRAINT DF__ADUSER__USER_NAM__14E61A24 DEFAULT ('') NOT NULL, PASSWORD NVARCHAR (32) NULL, USER_GROUP NVARCHAR (10) CONSTRAINT DF__ADUSER__USER_GRO__15DA3E5D DEFAULT ('') NOT NULL, SUSPENDED NVARCHAR (1) NULL, ...... }
对应于生成的业务实体,它的定义如下所示
有以下几个原因,需要重写控件来满足数据绑定的需要。
1 .NET自带的控件,大部分以字符串string的形式绑定数据,这会给非字符串类型的控件带来不方便。比如带小数的数据类型,带布尔值的数据类型。
2 为了减少界面层的重复代码。界面层中经常需要根据实体的属性来设置控件的对象状态。比如大小写状态,是否必须输入值,小数点位数。
下面的这段代码表达了这种需求,根据实体的附加属性,设置控件状态
Dictionary<string, string> fieldsCustProps = ComponentCommon.GetFieldsCustomProperties(entity, bindingInfo.BindingField); if (fieldsCustProps != null) { // handle caps lock property if (fieldsCustProps.ContainsKey("CapsLock")) { CharacterCasing = CharacterCasing.Upper; } // handle read only property if (fieldsCustProps.ContainsKey("ReadOnly")) { AlwaysReadOnly = true; } else if (fieldsCustProps.ContainsKey("AllowEditForNewOnly")) { _allowEditForNewOnly = true; } // handle hidden property if (fieldsCustProps.ContainsKey("Hidden")) { Visible = false; } // handle required property if (fieldsCustProps.ContainsKey("Required")) { _required = true; }
}
这样可以减少界面层中的重复代码。
3 部分控件有特殊的属性,必须要以重写来实现。比如经常遇到的lookup和drilldown。
查找(Lookup) :点击Customer No后面的小按钮,可以调出对话框,用来查找客户编号。
钻取(DrillDown): 当双击有下划线的文本框,比如Customer No时,它会跳转到客户主档,并打开对应的QSR的客户编号主档。
这两个特性,让功能与功能之间连接到一起,组成一个整体,相互引用和参考。日记帐引用主档的数据,查询引用日记帐的数据,让系统的可用性增色不少。
从基础的文本控件来看,如何重写它的功能以满足项目的需求。
[Designer(typeof(TextEditorDesigner))] public class TextEditor : Infragistics.Win.UltraWinEditors.UltraTextEditor, IEditor { private bool _isLayoutInitedFromBinding; private bool _isParentFormInited; private bool _isHidden; private bool _isInitializing; private bool _alwaysAllowEdit; private bool _alwaysReadOnly; private bool _allowEditForNewOnly; private bool _allowEdit; private bool _autoFind; private bool _hidden; private bool _required; private string _bindingField = string.Empty; ..... }
为什么不直接用.NET自带的TextBox呢?从上面的代码中可以看出一点头绪:
1 控件是否是必须输入的,这个功能.NET没有自带。对于必须输入值的控件,有的系统会在它的Label地方放一个星号,表示此控件项为必须输入,而重写之后,会在控件里面放一个红色箭头。
2 控件是否允许编辑 或是只允许新建立的时候编辑 有些数据项,比如销售单中的客户名称是从客户主档中带值过来,只能查看而不允许编辑。另一些数据项,比如销售单中的客户编码,在销售单保存后不再允许编辑。
3 是否允许控件查找值。如前面所讲述的,有些控件的值由其它主档数据带过来,则需要辅值查找。
4 与查找相同,有些控件需要查看它的主档属性,在控件中把值以下划线表示。双击值即可自动跳转到它的主档定义。