原创: Ankoe
前言
Nhibernate 查询数据返回集合为 Ilist 类型,由于 Ilist 实现了 Collection ,所以当 Ilist 绑定到 DataGridView 时,显示的字段并未按真实的顺序排序,造成显示的不适当。可以采用两种解决方法:
方法一:将 Ilist 转换成 DataSet
注: iList: 数据源
className: 类完全限定名
DllFile:className 所属的程序集名 如 :SysGUI.QdcLib.dll
public
DataSet
ConvertIListToDataSet(IListiList, stringclassName, stringDllFile)
{
Type
TheType = null;
if (DllFile != "")
{
Assembly
Assembly1 = Assembly.LoadFrom(DllFile);
TheType = Assembly1.GetType(className);
}
else
{
TheType = Type.GetType(className);
}
string
sTableName = NHibernate.Cfg.ImprovedNamingStrategy.Instance.ClassToTableName(className);
BindingFlags
bindFlag = BindingFlags.Public | BindingFlags.Instance;
PropertyInfo[] pInfos = TheType.GetProperties(bindFlag);
DataSet
dSet = newDataSet();
DataTable
dTable = dSet.Tables.Add(sTableName);
string
strColmunName ="";
foreach (PropertyInfoinfoinpInfos)
{
strColmunName = NHibernate.Cfg.ImprovedNamingStrategy.Instance.PropertyToColumnName(info.Name);
dTable.Columns.Add(strColmunName, info.PropertyType.GetType());
}
foreach(objectobjiniList){
DataRow
dRow = dTable.NewRow();
foreach(PropertyInfoinfoinpInfos){
strColmunName = NHibernate.Cfg.ImprovedNamingStrategy.Instance.PropertyToColumnName(info.Name);
dRow[strColmunName] = info.GetValue(obj, null);
}
dTable.Rows.Add(dRow);
}
return
dSet;
}
上面采用反射根据属性名及类型信息生成一个DataTable,然后用Ilist数据填充DataTable,这种方法有个不好的地方就是如果数据量大的时候,严重造成了程序的性能损失。
方法二:建一个表来保存所有表的字段信息,DataGridView加载Ilist数据以后再改变DataGirdView的显示方式。和方法一相比少了数据得制,性能也得以提升。
CREATE TABLE [SYS_ColumnDic] (
[AutoID] [int] NOT NULL ,-- 自动编号
[iTableID] [int] NOT NULL ,-- 表编号
[cEnglishName] [varchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,-- 英文字段名
[cLocalizeName] [varchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,-- 本地化字段名
[bVisible] [bit] NOT NULL CONSTRAINT [DF_SYS_ColumnDic_bVisible] DEFAULT (1),-- 是否显示
[iSortOrder] [int] NULL ,-- 排序序号
[iColumnWidth] [int] NOT NULL CONSTRAINT [DF_SYS_ColumnDic_iColumnWidth] DEFAULT (100),-- 列度
[cSpellCode] [varchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,-- 拼音码
CONSTRAINT [PK_SYS_ColumnDic] PRIMARY KEY CLUSTERED
(
[AutoID]
) ON [PRIMARY]
) ON [PRIMARY]
GO
上面的表是用来存储表的数据成员名信息,下面为了更清晰地介绍我并没有使该表,而是用 ArrayList 存储数据成员,你可以读取上表中存储的成员信息到 ArrayList 变量中使用。
现在来看改变 DataGridView 显示的代码:
using
System;
using
System.Collections.Generic;
using
System.Collections;
using
System.Text;
using
System.Windows.Forms;
namespace
SysGUI.DBConfig.Function
{
public
class
TableStyleHelper
{
///
<summary>
///
设置表头样式
///
</summary>
///
<param name="mDataGrid">
表控件对象
</param>
///
<param name="DataPropertyNames">
绑定数据成员
</param>
///
<param name="HeaderTexts">
绑定本地化标题
</param>
///
<param name="HeaderWidths">
表头宽度
</param>
public
void
SetTableHeaderText(System.Windows.Forms.DataGridViewmDataGrid,ArrayListDataPropertyNames, ArrayListHeaderTexts, ArrayListHeaderWidths)
{
DataGridViewColumnCollection
DGVColumnColl = mDataGrid.Columns;
for (inti = 0; i < DataPropertyNames.Count; i++)
{
for (intk = 0; k < mDataGrid.Columns.Count; k++)
{
int
t = FindColumnIndex(mDataGrid,DataPropertyNames[i].ToString());
if (t != -1)
{
DataGridViewColumn
tColumn;
if (mDataGrid.Columns[t].ValueType.ToString() == "System.Boolean")
{
tColumn = newDataGridViewCheckBoxColumn();
}
else
{
tColumn = newDataGridViewTextBoxColumn();
}
tColumn.DataPropertyName = mDataGrid.Columns[t].DataPropertyName;
tColumn.ValueType = mDataGrid.Columns[t].ValueType;
tColumn.ReadOnly = true;
if (HeaderTexts!=null)
{
tColumn.HeaderText = HeaderTexts[i].ToString();
}
if (HeaderWidths!=null)
{
if (Convert.ToInt32(HeaderWidths[i].ToString())==0){
tColumn.Visible = false;
}else{
tColumn.Width = Convert.ToInt32(HeaderWidths[i].ToString());
}
}
mDataGrid.Columns.Remove(mDataGrid.Columns[t]);
mDataGrid.Columns.Insert(i, tColumn);
break;
}
}
}
}
///
<summary>
///
查找列索引
///
</summary>
///
<param name="mDataGrid">
表控件
</param>
///
<param name="DataPropertyName">
数据成员
</param>
///
<returns></returns>
public
int
FindColumnIndex(System.Windows.Forms.DataGridViewmDataGrid, stringDataPropertyName)
{
int
index = -1;
for (intk = 0; k < mDataGrid.Columns.Count; k++)
{
if (DataPropertyName == mDataGrid.Columns[k].DataPropertyName)
{
index = mDataGrid.Columns.IndexOf(mDataGrid.Columns[k]);
break;
}
}
return
index;
}
public
void
ActiveEditColumn(System.Windows.Forms.DataGridViewmDataGrid, ArrayListEditDataPropertyNames)
{
//if (FindColumnIndex(mDataGrid,)
int
EditIndex=-1;
foreach (stringEditDataPropertyinEditDataPropertyNames)
{
EditIndex=FindColumnIndex(mDataGrid,EditDataProperty);
if (EditIndex!=-1){
mDataGrid.Columns[EditIndex].ReadOnly = false;
}
}
}
}
}
上面提供了
SetTableHeaderText
方法是用来改变表的显示样式的,含四个参数:
mDataGrid:
要改样式的表控件
DataPropertyNames:
绑定的数据成员->ArrayList
HeaderTexts:
绑定的本地化表头->ArrayList
HeaderWidths:
绑定的成员宽度->ArrayList
使用方法:
string
strHQL = "from SysGUI.QdcLib.Model.SYSTableDic";
SYSTableDicBLL
bll = new SYSTableDicBLL();
IList
lst = bll.GetAllTableDic(strHQL);
this.dataGridView1.DataSource = lst;
this.dataGridView2.DataSource = lst;
TableStyleHelper
TableStyleHelper1 = new TableStyleHelper();
ArrayList
cField = new ArrayList();
cField.Add("AutoID");
cField.Add("cTableName");
cField.Add("cTableRemark");
cField.Add("cMKeyName");
cField.Add("iMKeyStyle");
cField.Add("cIDentPrefix");
cField.Add("bIDentIsDate");
cField.Add("iIDentDType");
cField.Add("iIDentLength");
cField.Add("cSpellCode");
ArrayList
cTField = new ArrayList();
cTField.Add("
序号"
);
cTField.Add("
表名"
);
cTField.Add("
表注释"
);
cTField.Add("
主键名称"
);
cTField.Add("
主键样式"
);
cTField.Add("
标识前缀"
);
cTField.Add("
日期类型"
);
cTField.Add("
标识类型"
);
cTField.Add("
标识长度"
);
cTField.Add("
拼音码"
);
ArrayList
wTField = new ArrayList();
wTField.Add("80");
wTField.Add("100");
wTField.Add("100");
wTField.Add("100");
wTField.Add("100");
wTField.Add("100");
wTField.Add("100");
wTField.Add("100");
wTField.Add("100");
wTField.Add("100");
ArrayList
eTField = new ArrayList();
eTField.Add("cTableRemark");
eTField.Add("cMKeyName");
eTField.Add("iMKeyStyle");
eTField.Add("cIDentPrefix");
eTField.Add("bIDentIsDate");
TableStyleHelper1.SetTableHeaderText(dataGridView1, cField, cTField, wTField);
TableStyleHelper1
.ActiveEditColumn(dataGridView1, eTField);
DataGridView1是用前面介绍的方法二实现的,DataGridView2是直接绑定Ilist集合显示的结果。按方法二你可以提供可以自定义表列显示的顺序、大小及是否显示。
浙公网安备 33010602011771号