C# Code
using System.Data.Entity;
using System.Reflection;
namespace DataGridView4CellFormatting
{
public partial class Form2 : Form
{
EFDbContext context;
BindingSource bsOrder;
public Form2()
{
InitializeComponent();
context = new EFDbContext();
bsOrder = new BindingSource();
}
private void Form2_Load(object sender, EventArgs e)
{
context.Order.Include(c => c.Customer).Load();
bsOrder.DataSource = context.Order.Local.ToBindingList();
dgvOrders.AutoGenerateColumns = false;
dgvOrders.DataSource = bsOrder;
}
private readonly char DataPropertyNameSign = '.' ;
private void dgvOrders_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
object obj = dgvOrders.Rows[e.RowIndex].DataBoundItem;
string DataPropertyName = dgvOrders.Columns[e.ColumnIndex].DataPropertyName;
if (obj != null &&
DataPropertyName.Contains(DataPropertyNameSign))
{
e.Value = BindNavigationProperty(obj, DataPropertyName);
}
}
/// <summary>
/// 註解以該範例來說明註記,方便事後回憶
/// </summary>
/// <param name="Property">Order Class</param>
/// <param name="DataPropertyName">Customer.CustName</param>
/// <returns>CustName 資料</returns>
private string BindNavigationProperty(object Property, string DataPropertyName)
{
if (DataPropertyName.Contains(DataPropertyNameSign) == false)
{
throw new Exception($"{nameof(DataPropertyName)} 資料不符合導覽屬性規則");
}
// Customer.CustName
var DataPropertyInfo = ParseDataPropertyName(DataPropertyName);
// Customer
string NavigatrionPropertName = DataPropertyInfo.NavigationPropertyName;
// CustName
string PropertyName = DataPropertyInfo.PropertyName;
// 取回 Order.Customer 相關資料
var obj = GetPropertyValue(Property, NavigatrionPropertName);
// 取回 Customer.CustName 資料
return GetPropertyValue(obj, PropertyName).ToString();
}
/// <summary>
/// 取得 object Property Value
/// </summary>
/// <param name="obj">欲取值的 object </param>
/// <param name="propertyName">屬性</param>
/// <returns>屬性值</returns>
private object GetPropertyValue(object obj, string propertyName)
{
Type t = obj.GetType();
// BindingFlags.IgnoreCase 表示不區分大小寫,Flag 只要重新設定就要全部都設,只設單一個會沒有效果
PropertyInfo info = t.GetProperty(propertyName, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
if (info == null)
{
throw new Exception($"Property:{nameof(propertyName)} 不存在,無法取值");
}
object oValue = info.GetValue(obj, null);
if (oValue == null)
{
throw new Exception($"無法取得 Property:{nameof(propertyName)} 的值");
}
return oValue;
}
/// <summary>
/// 解析 DataPropertyName
/// </summary>
/// <param name="DataPropertyName">DataPropertyName</param>
/// <returns>ClassName 和 PropertyName </returns>
private (string NavigationPropertyName, string PropertyName) ParseDataPropertyName(string DataPropertyName)
{
if (string.IsNullOrEmpty(DataPropertyName))
{
throw new ArgumentNullException(nameof(DataPropertyName));
}
string[] result = DataPropertyName.Split(DataPropertyNameSign);
int ArraryLength = 2;
if (result.Length != ArraryLength)
{
string ErrorMessage = $"{nameof(DataPropertyName)} 參數格式必須為 ClassName.PropertyName,傳入值為 {DataPropertyName}";
throw new ArgumentException(ErrorMessage);
}
return (result[0], result[1]);
}
}
}
- 重點1:BindingFlags.IgnoreCase [Highlight 76 77 行]
- 重點2:SQL Profile 側錄 TSQL 語法
沒有留言:
張貼留言