目录
关于属性统一设置
数据感应也即数据捆绑,是一种动态的,web控件与数据源之间的交互,属性统一设置 ,是指业务规则,通过配置数据,统一对数据控件的属性进行赋值,以达到灵活应用的目的。比如是否为必填写项的设置,以便于统一操作。
如图其中放置了一些标签(label)控件、(textbox)文本框控件、(dropdownlist)下拉列表框,用于录入及选择一些值,比如现工作单位、参加工作时间、职称、职务等信息。
实际业务中,如不同的用户类型,相同的注册界面,则可考虑某些输入项的必填写属性的变化,如没有工作单位的则无须填写现工作单位和参加工作时间,反之在职人员则必须填写(图中标签带有*号的均为必填写项的提示性标志)。根据统一属性设置,可以显示如下图:
图中的现工作单位和参加工作时间前面的*号不存了,则表示为不必填写项,以避免输入“无” 字来“绕” 过检查。
准备数据源
我们在 ms sql server 创建表 cfg_ypz(配置数据视图),其结构如下表:
序号 | 字段名 | 类型 | 说明 |
---|---|---|---|
1 | fname | nvarchar | 控件主名(如字段名) |
2 | cname | nvarchar | 属性值 |
我们假设界面有如下控件,代码如下:
<div >
<asp:label id="l_xgzdw" runat="server"></asp:label>
<asp:textbox id="x_xgzdw" checkschema="maxlen50" runat="server" />
<asp:label id="l_cjgzsj" runat="server"></asp:label>
<asp:textbox id="x_cjgzsj" checkschema="maxlen50" runat="server" />
</div>
其中,xgzdw (现工作单位)和 cjgzsj (参加工作时间)即为控件主名,而 l_ 前缀为标签提示控件,x_ 前缀为输入控件,那么我们可以初始化配置数据, sql语句如下:
insert into cfg_ypz (fname,cname) values('xgzdw','现工作单位')
insert into cfg_ypz (fname,cname) values('cjgzsj','参加工作时间')
最后我们将数据填充到 datareader ,并生成对应的二维数组。
范例运行环境
操作系统: windows server 2019 datacenter
数据库:microsoft sql server 2016
.net版本: .netframework4.0 或以上
开发工具:vs2019 c#
attributeinducingfieldname 方法
设计与实现
attributeinducingfieldname 方法主要是通过 object[,] 二维对象数组数据源进行提取并根据主控件名与控件id进行匹配,查找匹配成功则根据配置参数的进行统一属性赋值,其参数设置见下表:
序号 | 参数名 | 类型 | 说明 |
---|---|---|---|
1 | hastitle | bool | 数据集是否包含列名,如果包含则数据输出从第2行开始 |
2 | cfg | arraylist | 必须值,一个配置参数列表,每一个项为一个一维字符串数组,最多有个4个值,项目的数目为必须有2个值或者4个值。 (1)2个值的情况,指要赋值控件的前缀,后面为属性名称,如 new string[] { "x_", "onclick" } 表示为按主控件名+x_前缀名进行查找,并赋予 onclick 属性(值 根据数据配置表进行设置) (2)4个值的情况,如 new string[]{ "l_", "","x_","*" } ,前2个值可以设置为空略过,后两个值为必填写项的设置,第4个值为必填写项的提示字符前缀,如“*”号 |
方法中会用到 getreaderdata 方法可以访问数据库数据表进行查询结果的提取,并转化为 object[,] 二维数组,具体实现请参考我的文章:《c# web控件与数据感应之 填充 htmltable》中的getreaderdata 方法实现代码。
attributeinducingfieldname 方法实现代码如下:
arraylist paras=new arraylist();
string refsql="";
system.data.commandtype ct=system.data.commandtype.text;
public void attributeinducingfieldname(bool hastitle,arraylist cfg)
{
object[,] readerdata = getreaderdata("sqlserver","您的连接串",refsql,paras,hastitle,ct);
if (readerdata == null) return;
if (readerdata.getlength(1) < 2) return;
for (int i = (hastitle == true ? 1 : 0); i < readerdata.getlength(0); i++)
{
string _fieldname = readerdata[i,0].tostring();
string _cname = readerdata[i, 1].tostring();
for (int j = 0; j < cfg.count; j++)
{
string[] _cfg=(string[])cfg[j];
string exname = _cfg[0];
string attribute = _cfg[1];
string autoreqchar = "";
string relaexname = "";
if (_cfg.getlength(0) > 3)
{
relaexname = _cfg[2];
autoreqchar = _cfg[3];
}
control ctl = findcontrolex(exname+_fieldname);
if (ctl != null)
{
if (attribute == "")
{
if (relaexname != "")
{
control ctl2 = findcontrolex(relaexname + _fieldname);
if (ctl2 is webcontrol)
{
string _checkschema = ((webcontrol)ctl2).attributes["checkschema"];
if (_checkschema != null)
{
if (_checkschema.indexof("notnull") != -1)
{
_cname = autoreqchar + _cname;
}
}
}
}
setbaseclasstext(exname + _fieldname, _cname);
}
else
{
if (attribute.tolower() != "style")
{
if (((webcontrol)ctl).attributes[attribute] == null)
{
((webcontrol)ctl).attributes[attribute] = _cname;
}
}
else
{
string[] styles = _cname.split(';');
for (int s = 0; s < styles.length; s++)
{
string[] style = styles[s].split(':');
if (style.length > 1)
{
string _key = style[0];
string _value = style[1];
((webcontrol)ctl).style[_key] = _value;
if (_key.tolower().trim() == "visible" && _value.tolower().trim() == "false")
{
((webcontrol)ctl).visible = false;
}
}
}
}//style
}
}
}
}//for rows
}//control inducing fieldname
public void setbaseclasstext(string webctl,string values)
{
system.web.ui.control btnctl;
btnctl=findcontrolex(webctl);
if(btnctl==null)
{
return;
}
if(btnctl.gettype()==typeof(system.web.ui.webcontrols.textbox))
{
((system.web.ui.webcontrols.textbox)btnctl).text=values;
}
if(btnctl.gettype()==typeof(system.web.ui.webcontrols.label))
{
((system.web.ui.webcontrols.label)btnctl).text=values;
}
if(btnctl.gettype()==typeof(system.web.ui.webcontrols.button))
{
((system.web.ui.webcontrols.button)btnctl).text=values;
}
if(btnctl.gettype()==typeof(system.web.ui.webcontrols.linkbutton))
{
((system.web.ui.webcontrols.linkbutton)btnctl).text=values;
}
if(btnctl.gettype()==typeof(system.web.ui.webcontrols.hyperlink))
{
((system.web.ui.webcontrols.hyperlink)btnctl).text=values;
}
}
如何根据 id 查找控件
findcontrolex 实现了对 findcontrol 方法的扩充,如果查找不成功可试图查找是否有母版页,如果存在,则根据母版页模式继续查找。
findcontrolex 方法
findcontrolex 通过传递要查找的服务器容器控件和id参数,以返回查找到的控件,代码如下:
public control findcontrolex(control findpage,string id)
{
control ctl=findpage.findcontrol(id);
if (ctl == null && findpage.page.master != null)
{
ctl=findpage.page.master.findcontrol(id);
}
return ctl ;
}
调用示例
前端代码请参照准备数据源小节示例:
示例(1)将查询出来的配置数据指定的控件设置为必填写项,并为其自定义属性(cname)进行赋值,代码如下:
string refsql="select fname,cname from cfg_ypz";
system.data.commandtype ct=system.data.commandtype.text;
arraylist cfg = new arraylist();
cfg.add(new string[]{ "l_", "","x_","*" });
cfg.add(new string[] { "x_", "cname" });
attributeinducingfieldname(true,cfg);
示例(2)将查询出来的配置数据指定的控件为其 onclick 属性进行赋值,代码如下:
string refsql="select fname,'onclick_funtion()' as cname from cfg_ypz";
system.data.commandtype ct=system.data.commandtype.text;
arraylist cfg = new arraylist();
cfg.add(new string[] { "x_", "onclick" });
attributeinducingfieldname(true,cfg);
小结
配置数据的 cname 属性值,如果值中有 "visible:false" 键值,则可以对控件进行 visible 的进行 false 设置,这是根据项目实际的一些需要进行的功能实现。以上就是关于控件属性统一设置的介绍,我们可以根据自己的实际需要进行改造和功能扩充,本示例代码仅供您参考。
感谢您的阅读,希望本文能够对您有所帮助。
发表评论