今天记录一下SearchLookUpEdit在工作期间二次封装的过程
SearchLookUpEdit作为一个下拉控件,无论是美观性还是易用性觉得做得都挺不错,在刚使用Dev时,还没注意到这个控件,一直在用LookUpEdit,后来在网上找资料时才发现这 个,然后就把LookUpEdit给填的掉了。
对于SearchLookUpEdit的界面设置方法,以及基本的使用这里就不多说了,网上有很多,大家可自行百度,直接放上效果图和基类源码:
效果图:
列信息类:
public class BaseSlueColumn
{
string str_colCode = string.Empty; //字段实际名
string str_colName = string.Empty; //字段显示名
//字段类型 只有ID,DISPLAY,COL三种情况;
//ID代表列为ID列,不显示;
//DISPLAY代表选择后在选择框里显示的值
//COL代表只在下拉框中显示,方便用户了解每条数据的信息
string str_colType = string.Empty;
public string Str_colCode
{
get { return str_colCode; }
set { str_colCode = value; }
}
public string Str_colName
{
get { return str_colName; }
set { str_colName = value; }
}
public string Str_colType
{
get { return str_colType; }
set { str_colType = value; }
}
}
封装类:
public partial class BaseSearchLookUpEdit : UserControl
{
//传入的数据
DataTable dt;
//字段值
public string str_id = string.Empty;
public string str_display = string.Empty;
//字段名
string str_fieldId = string.Empty;
string str_fieldDisplay = string.Empty;
PublicClass pc = new PublicClass();
//定义委托
public event EventHandler EditValueChanged;
public BaseSearchLookUpEdit()
{
InitializeComponent();
}
/// <summary>
/// 加载下拉信息
/// </summary>
public void init(DataSet ds, ArrayList colList)
{
slueInfo.Properties.DataSource = null; //清空数据源
if (ds == null)
{
slueInfo.Properties.DataSource = null;
return;
}
slueInfo.Properties.DataSource = ds.Tables[0]; //赋值数据源
dt = ds.Tables[0];
slueInfo.Properties.View.Columns.Clear();//清空列
//循环添加列
foreach (BaseSlueColumn bsc in colList)
{
//ID列
if (bsc.Str_colType.Equals("ID"))
{
slueInfo.Properties.ValueMember = bsc.Str_colCode;
str_fieldId = bsc.Str_colCode;
GridColumn columnID = this.slueInfo.Properties.View.Columns.AddField(bsc.Str_colCode);
columnID.AppearanceHeader.TextOptions.HAlignment = DevExpress.Utils.HorzAlignment.Center;
columnID.Caption = bsc.Str_colName;
columnID.Visible = false;
}
//显示列
if (bsc.Str_colType.Equals("DISPLAY"))
{
slueInfo.Properties.DisplayMember = bsc.Str_colCode;
str_fieldDisplay = bsc.Str_colCode;
GridColumn columnName = this.slueInfo.Properties.View.Columns.AddField(bsc.Str_colCode);
columnName.AppearanceHeader.TextOptions.HAlignment = DevExpress.Utils.HorzAlignment.Center;
columnName.Caption = bsc.Str_colName;
columnName.Visible = true;
}
//其它列
if (bsc.Str_colType.Equals("COL"))
{
GridColumn columnCol = this.slueInfo.Properties.View.Columns.AddField(bsc.Str_colCode);
columnCol.AppearanceHeader.TextOptions.HAlignment = DevExpress.Utils.HorzAlignment.Center;
columnCol.Caption = bsc.Str_colName;
columnCol.Visible = true;
}
}
}
/// <summary>
/// 下拉修改事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void slueInfo_EditValueChanged(object sender, EventArgs e)
{
if (this.slueInfo.EditValue == null)
{
return;
}
str_id = this.slueInfo.EditValue.ToString();
str_display = this.slueInfo.Text;
if (EditValueChanged != null)
{
EditValueChanged(this, e);
}
}
/// <summary>
/// 获取指定列数据
/// </summary>
/// <param name="str_colName"></param>
/// <returns></returns>
public string GetColValue(string str_colName)
{
if (string.IsNullOrEmpty(str_id) || string.IsNullOrEmpty(str_colName))
{
return null;
}
DataTable dt_new = new DataTable();
dt_new = dt.Clone(); // 克隆dt 的结构,包括所有 dt 架构和约束,并无数据;
DataRow[] rows = dt.Select( this.str_fieldId + " = '" + this.str_id + "'"); // 从dt 中查询符合条件的记录;
foreach (DataRow row in rows) // 将查询的结果添加到dt中;
{
dt_new.Rows.Add(row.ItemArray);
}
if (dt_new.Rows.Count <= 0)
{
return null;
}
return dt_new.Rows[0][str_colName].ToString(); //返回值
}
/// <summary>
/// 设置为空
/// </summary>
public void SetNull()
{
this.slueInfo.EditValue = "";
this.slueInfo.Text = "";
this.str_id = string.Empty;
this.str_display = string.Empty;
}
public void SetValue(string str_value)
{
this.slueInfo.EditValue = str_value;
}
//是否只读
public void ReadOnly(Boolean bl)
{
if (bl)
{
slueInfo.Properties.ReadOnly = true;
}
else
{
slueInfo.Properties.ReadOnly = false;
}
}
}
封装这个控件的要求,第一使用起来要方便,第二就是列的无限扩展性,并且能够获取选中行的任意一列数值。
第一点实现起来很简单,对外开放一个方法,加几个参数即可;
主要是第二点,既然想无限扩展,最好的方式就是将列看成一个对象加入集合,再把集合当成参数传进来,上面的列信息类【BaseSlueColumn】就是那个对象。该类共有三个属性,【str_colCode】代表列的实际名称,【str_colName】代表列要显示的名称,【str_colType】代表列的类别,类别我规定只有三个值:【ID】、【DISPLAY】、【COL】
这个类别是什么意思呢?如果大家对这个控件有点了解的话就会知道,这个控件有两个属性【ValueMember】和【DisplayMember】,一个代表显示值,即我选中一条信息后,选择框中看到的文本,一个是实际值,一般来说是表中的ID。那么【ID】对应的是【ValueMember】,【DISPLAY】对应的是【DisplayMember】,而【COL】则代表其它扩展列,可在下拉框中显示,作为用户的参照信息
我们将每个列都定成一个【BaseSlueColumn】的对象,然后放入集合中,就达到了扩展的目的,代码如下:
public static ArrayList GetBaseSystemCol()
{
ArrayList al_col = new ArrayList();
BaseSlueColumn bscId = new BaseSlueColumn();
bscId.Str_colCode = "SYSTEM_ID";
bscId.Str_colName = "角色ID";
bscId.Str_colType = "ID";
BaseSlueColumn bscName = new BaseSlueColumn();
bscName.Str_colCode = "SYSTEM_NAME";
bscName.Str_colName = "角色名称";
bscName.Str_colType = "DISPLAY";
BaseSlueColumn col2 = new BaseSlueColumn();
col2.Str_colCode = "SORT_NO";
col2.Str_colName = "顺序";
col2.Str_colType = "COL";
al_col.Add(bscId);
al_col.Add(bscName);
al_col.Add(col2);
return al_col;
}
接下来,重点说下封装类【BaseSearchLookUpEdit】,类中有五个主要方法:
1、Init方法:参数为DataSet,ArrayList,DataSet为传入的数据集合,ArrayList为上面说到列对象集合。
作为初始化方法,一般在窗体加载时调用,方法中根据每个列中的【Str_colType】属性,来定义控件的【ValueMember】和【DisplayMember】;
2、slueInfo_EditValueChanged方法:这个属于控件自带的方法,每次下拉值修改后,我们都将属性【str_id】和【str_display】及时更改,以便可以获取正确的数据;
3、SetNull方法:置空下拉列;
4、ReadOnly方法:是否只读;
5、GetColValue方法:参数【str_colName】,代表要获取数据的列名,当选中一条数据,通过该方法,即可获得该行某列的数据。需要注意一点,如果ID值不是唯一的,那么这里只会返回第一条数据,大家有需求的话,可自行修改;
粘一下主要的调用的代码:
1、初始化
HisDeptDict hdd = new HisDeptDict();
DataSet ds_dept = hdd.GetHisDataByDept("AND io_attr='ZY' AND dept_code in (select d.dept_code from BASE_USER_DEPT d where d.user_id ='" + Globals.str_gUserId + "')");
this.slueDept.init(ds_dept, SetColClass.GetDeptCol());
SetColClass.GetDeptCol():
//科室下拉列设置
public static ArrayList GetDeptCol()
{
ArrayList al_col = new ArrayList();
BaseSlueColumn bscId = new BaseSlueColumn();
bscId.Str_colCode = "DEPT_CODE";
bscId.Str_colName = "科室编码";
bscId.Str_colType = "ID";
BaseSlueColumn col1 = new BaseSlueColumn();
col1.Str_colCode = "DEPT_CODE";
col1.Str_colName = "科室编码";
col1.Str_colType = "COL";
BaseSlueColumn col2 = new BaseSlueColumn();
col2.Str_colCode = "ABBREVIATION";
col2.Str_colName = "简拼";
col2.Str_colType = "COL";
BaseSlueColumn bscName = new BaseSlueColumn();
bscName.Str_colCode = "DEPT_NAME";
bscName.Str_colName = "科室名称";
bscName.Str_colType = "DISPLAY";
al_col.Add(bscId);
al_col.Add(col1);
al_col.Add(bscName);
al_col.Add(col2);
return al_col;
}
2、GetColValue:
string str_systemDesc = slueInsurSystem.GetColValue("SYSTEM_DESC");
最后说一点,不知道为什么,DEV中所有的控件继承后进行重写,生成后在工具箱都看不到(C#自带的DataGridView可以),不过我看网上却有人实现了,不知道设置了什么。只好退而求次,直接把控件拉到UserControl,然后再自己写方法。这种方法对于大部分控件来说倒没什么,主要是GridContrl让人很郁闷,拉进去再生成控件,右下角的设置卡片就消失了,只能动态生成列,开发时太麻烦,如果大家有解决的办法请留言告诉我下,谢谢!