應(yīng)用場景:1用SQL語句從數(shù)據(jù)庫返回一個DataTable對象,2然后綁定到DataGridView控件上,DataGridView列頭顯示的是數(shù)據(jù)庫里的英文字段名,3要顯示中文,需要建個對應(yīng)的EM實體模型府怯,并設(shè)置DisplayName特性;4DataGridView的某一行數(shù)據(jù)賦值給EM實體實例防楷;5EM實體實例綁定到PropertyGrid控件上牺丙;6在PropertyGrid上進行增刪改查的操作是很方便的。
1窗口布局
新建一個WinForm項目:ReflectionAndAttribute复局;擺放一個SplitContainer冲簿,Dock=Fill;左邊放一個DataGridView:dgv亿昏,Dock=Fill峦剔;右邊放一個PropertyGrid:pg,Dock = Fill龙优;創(chuàng)建好后布局大概如下圖:
2綁定DataGridView:dgv
-窗口創(chuàng)建Load事件,代碼如下:
private void Form1_Load(object sender, System.EventArgs e)
{
OracleDML.ConnectionString = "Data Source=CQYH;User Id=nmis;password=nmis";
DataTable dt = OracleDML.AllTables();
dgv.DataSource = dt;
}
-其中OracleDML.AllTables()代碼如下:
/// <summary>
/// 數(shù)據(jù)庫的全部表
/// </summary>
/// <returns></returns>
public static DataTable AllTables()
{
string sql_tables = @"select TABLE_NAME,COMMENTS ,TABLE_TYPE
from user_tab_comments
where table_type = 'TABLE'
order by table_name";
DataTable allTables = OracleDML.GetDataTable(sql_tables);
allTables.TableName = "allTables";
return allTables;
}
-其中OracleDML.GetDataTable()代碼如下:
/// <summary>
/// 查詢SQL_select,返回一個DataTable 彤断, 200207 add by Sufuq
/// </summary>
/// <param name="cmdText"></param>
/// <returns></returns>
public static DataTable GetDataTable(string SQL_select)
{
//OracleCommand cmd = new OracleCommand();
using (OracleConnection connection = new OracleConnection(ConnectionString))
{
OracleDataAdapter ada = new OracleDataAdapter(SQL_select, connection);
//OracleCommandBuilder ocb = new OracleCommandBuilder(ada); //更新時需要這個
DataTable dt = new DataTable();
ada.Fill(dt);
return dt;
}
}
-綁定后的運行效果
3創(chuàng)建EM實體類AllTables
創(chuàng)建換一個EM實體類野舶,并加上[DisplayName()]特性
using System.ComponentModel;
namespace ReflectionAndAttribute
{
class AllTables
{
[DisplayName("表名")]
public string TABLE_NAME { get; set; }
[DisplayName("中文名")]
public string COMMENTS { get; set; }
[DisplayName("類型")]
public string TABLE_TYPE { get; set; }
}
}
4重點來了列頭變中文名
-Form1_Load添加如下一樣代碼:
//列頭設(shè)置為中文
AttributeHelper.SetColumnDisplayName(typeof(AllTables), dgv);
-其中SetColumnDisplayName()用到反射和特性
/// <summary>
/// 根據(jù)DataGridView綁定數(shù)據(jù)源的列名獲取EM實體模型的顯示名,用來設(shè)置列標(biāo)題宰衙。
/// </summary>
/// <param name="em"></param>
/// <param name="dgv"></param>
public static void SetColumnDisplayName(Type em , DataGridView dgv)
{
for (int i = 0; i < dgv.Columns.Count; i++)
{
string colName = dgv.Columns[i].Name;
string DisName = GetDisplayName(em, colName);
dgv.Columns[i].HeaderCell.Value = DisName;
}
}
/// <summary>
/// 獲取類的DisplayName顯示名
/// </summary>
/// <param name="modelType">類名</param>
/// <param name="propertyDisplayName">類屬性名</param>
/// <returns></returns>
public static string GetDisplayName(Type modelType, string propertyDisplayName)
{
DisplayNameAttribute dna = TypeDescriptor.GetProperties(modelType)[propertyDisplayName].Attributes[typeof(DisplayNameAttribute)] as DisplayNameAttribute ;
string displayName = "";
if (dna == null)
{
displayName = propertyDisplayName;
}
else
{
displayName = dna.DisplayName;
}
return displayName;
//return (TypeDescriptor.GetProperties(modelType)[propertyDisplayName].Attributes[typeof(DisplayNameAttribute)] as DisplayNameAttribute).DisplayName;
}
5DataGridView某行數(shù)據(jù)實例化allTables并綁定PropertyGrid
-Form1上dgv添加RowEnter事件
private void dgv_RowEnter(object sender, DataGridViewCellEventArgs e)
{
if (e.RowIndex >= 0 && e.ColumnIndex >= 0)
{
int row = e.RowIndex;
//DataGridview行數(shù)據(jù)實例化AllTables
AllTables em = AttributeHelper.DgvRowBindTOEM(dgv, row, typeof(AllTables)) as AllTables;
//綁定到PropertyGrid
pg.SelectedObject = em;
}
}
-其中DgvRowBindTOEM用到反射和特性
/// <summary>
/// DataGridView的某行綁定到實體模型EM
/// </summary>
/// <param name="dgv"></param>
/// <param name="row"></param>
/// <param name="em"></param>
/// <returns></returns>
public static object DgvRowBindTOEM(DataGridView dgv ,int row,Type tEM)
{
//根據(jù)類型實例化一個對象
object emReturn = System.Activator.CreateInstance(tEM);
//dgv的一行數(shù)據(jù)復(fù)制給實體模型對象
for (int i = 0; i < dgv.Columns.Count; i++)
{
string colName = dgv.Columns[i].Name.ToLower(); //數(shù)據(jù)庫名 = 列名.ToLower = 屬性名
//string pName = StringHelper.FirstUpper(colName);//這里還可以加列名轉(zhuǎn)屬性名
PropertyInfo pInfo = tEM.GetProperty(colName); //根據(jù)列名取屬性信息
object value = dgv.Rows[row].Cells[colName].Value; //列的數(shù)據(jù)值
if (value == System.DBNull.Value) value = value.ToString(); //數(shù)據(jù)庫null轉(zhuǎn)換為string
pInfo.SetValue(emReturn,value,null); //賦值給實例對象colName屬性
}
return emReturn;
}
-最終完成效果
6對數(shù)據(jù)的增刪改查
6.1查詢平道, DataGridView的查詢過濾參閱http://www.reibang.com/p/b3d6ff3c93d6
6.2新增,只要把綁定在PropertyGrid的類清空即可
比如這樣:
AllTables em = new AllTables();
pG.SelectedObject = em;
6.3刪除,只要把PropertyGrid綁定的類傳給數(shù)據(jù)訪問層操作即可
AllTables em = (AllTables )pG.SelectedObject;
OracleDML.Delete(em);
6.4修改供炼,只要把PropertyGrid綁定的類傳給數(shù)據(jù)訪問層操作即可
AllTables em = (AllTables )pG.SelectedObject;
OracleDML.Update(em);